ラベル Programming の投稿を表示しています。 すべての投稿を表示
ラベル Programming の投稿を表示しています。 すべての投稿を表示

2012年8月31日金曜日

astah Scriptで遊ぼう

astah*が、JavaScriptでastahにアクセスできるプラグイン「astah Script」を出してた。ホントはETロボコンのモデルを書かなきゃいけないから遊んでる場合じゃないんだけど、遊んでたらおもしろかったので…。色々書いてみて遊んだメモを残しておく。

インストールや基本的な動かし方は、公式サイトを見てください。あと、今回作ったスクリプトは別エントリで公開しようと思ってる。例によって、VDM絡みのスクリプト。

気をつけること

getNameで取れるのは、JavaScriptのStringではない

Javaのjava.lang.Stringじゃないかと。
文字列比較が == ではできなくてequals使う必要あるし、typeofするとObjectになる。

getProjectで取れる要素の意味

開いているプロジェクトのトップ階層がAPI説明で言うところの「起点となるモデル」。
最初分からなくて、自分で取得するメソッド書いてた…。

JavaScriptのArrayクラスが持つindexOfは使えない

なぜだろう???そんなメソッドないエラーが出る。

Tips

UML版やPro版で可能なモデルの編集にはimportを追加する

importPackage(com.change_vision.jude.api.inf.editor);

XMIエクスポートみたいに、ファイルやディレクトリが絡むとMacとWindowsの関係が面倒

下のような関数を作って対応。ただし、ファイル名やディレクトリ名に円マーク使った場合は正常に動かない
var dirName = getCurrentDirectory(astah.getProjectPath());

function getCurrentDirectory(fullPath) {
  var enPos = fullPath.lastIndexOf("¥¥");
  var slaPos = fullPath.lastIndexOf("/");
  return fullPath.substring(0, enPos >= slaPos ? enPos + 1 : slaPos + 1);
}

配列に含まれているか?のindexOfは、自分で実装

Arrayとastahから取れるStringをもらって判定。仕様はJavaScriptのindexOfと一緒で、見つからなければ-1を返す。
function indexOf(org, element) {
  for (var i in org) {
    if (org[i].equals(element)) {
      return i;
    }
  }
  return -1;
}

astah.close()すると、モデルを書き換えていてもいきなり閉じる

保存しますか?ダイアログ出ないので注意
今回の用途だと、モデルは一時的に書き換えたいだけだから良かった

要求図で、起点モデルから要求の包含関係を辿るスクリプト

ただし、satisfyやderiveReqtで繋がる要求まではカバーしない
importPackage(com.change_vision.jude.api.inf.model);

var req = astah.findElements(IRequirement);
for(var i in req) {
  if (req[i].getNestedClasses().length != 0) {
    if (req[i].getOwner().getName() == astah.getProject().getName()) {
      println(req[i].getName());
      printNestClass(req[i], 1);
    }
  }
}

function printNestClass(req, depth) {
  var nestClasses = req.getNestedClasses();
  for(var j in nestClasses) {
    for(var k = 0; k < depth; k++) { print("    "); }
      println("|- " + nestClasses[j].getName());
      if (nestClasses[j].getNestedClasses().length != 0) {
        printNestClass(nestClasses[j], ++depth);
      }
    }
  }

使ってみて思ったこと

  • おもしろい、簡単
  • JavaScript上の問題なのかJavaの問題なのかが切り分け辛い
  • Groovyあたりで書いた方がJavaとの親和性も高くてやりやすいかも
    • Groovyで書いておけば、astah Scriptでちょろっと試して、それをプラグインまで持ってくのがラクかも

2010年11月11日木曜日

[Java] 配列をディープコピーする

Javaで配列をコピーする時に、ディープコピーが必要なのに、シャローコピーをしていて、複数のオブジェクトが全て同じ参照になってしまい、ハマったのでディープコピーする方法を残しておく。
配列を、以下のように単純に代入するとシャローコピーになり、配列オブジェクトへの参照がコピーされるだけになる。なので、aaa配列の中身を書き換えると、bbb配列の中身も書き換わる。
String[] aaa = {"1", "2", "3", "4"};
String[] bbb = aaa;
 
System.out.println(Arrays.toString(aaa));
System.out.println(Arrays.toString(bbb));
 
aaa[2] = "7";

System.out.println(Arrays.toString(aaa));
System.out.println(Arrays.toString(bbb));
これを、以下のようにArraysクラスのcopyOfメソッドを使うと、ディープコピーとなり、配列の中身をコピーした別のオブジェクトとしてコピーしてくれるなので、aaa配列の中身を書き換えても。bbb配列の中身は書き換わらない。
String[] aaa = {"1", "2", "3", "4"};
String[] bbb = Arrays.copyOf(aaa, aaa.length);

System.out.println(Arrays.toString(aaa));
System.out.println(Arrays.toString(bbb));

aaa[2] = "7";

System.out.println(Arrays.toString(aaa));
System.out.println(Arrays.toString(bbb));

2010年10月12日火曜日

形式手法とコーディングと仕様不具合と・・・

ちょっと物思いにふけってたら、思いついたことがあったのでメモ。

きっかけは、今のプロジェクト。今は、実装工程の後半に差し掛かってる。で、この間、今さら影響度の大きい問題が見つかった。仕様策定時は、自分も含めて問題ないと思っていた箇所。業務を進める上での、とあるナンバーリングに不整合が出ることが分かった。

ここで思ったのは、ちゃんと仕様を書ききれてないからコーディング時になっても仕様不具合が見つかる、ということ。やっぱ何らかの形で論理的に矛盾のない記述をしないと仕様不具合は取れない。しかも、手戻りコストを考えると、それは開発プロセスの初期段階でなされるべき。

じゃあそれをプログラミング言語でやるか?それも1つの答えだとは思う。でも、再利用性や仕様レベルを書く時の生産性、そもそもの向き不向きを考えると、プログラミング言語で書くのは、プロジェクト全体でオーソライズされない限りは現実的ではないかなと思う。

こんなことを諸々考えてると、やっぱり形式手法で仕様を書いておきたくなる。導入コスト・障壁等の問題があることは分かるけど、できるところからやっていきたいよね。まずは書くところから、次にそれを検証するところ。その検証も色んなレベルがあるから、目指す所を決めて、そこに向かって少しずつ進めるといいなぁ。

まとめると、形式手法を使って、まずは仕様を書きませんか?ってこと。

2010年5月18日火曜日

【備忘録】8つのバッチファイル用のコードスニペット

普段の仕事で簡単なスクリプトが必要になった時は、Cygwinでシェルスクリプトを書く。でも、たまーに、1年に1回ぐら いバッチファイルを書く機会がある。1年に1回ぐらいだし、だいたい後ろ向きな理由で書くことが多いので、毎回同じようなことを検索してる。年に1回とは いえ、効率が悪いので、備忘録としていくつか書いておく。

正規表現で文字列検索:findstr

使ったオプショ ン

  • /v パターンにマッチしない行を抜き出す
  • /e 行末にマッチする
  • /c:"" ""内の文字列にマッチする
  • /i 大文字小文字の区別なくパターンマッチ

記述例

findstr /v /e /c:" " tree.txt
tree.txtから空白で終わらない行を抜き出す
findstr /v .txt$ tree.txt
tree.txtから.txtで終わらない行を抜き出す
findstr /v /e /c:" " tree.txt | findstr /v \.txt$ | find /v /c ""
tree.txtから.txtで終わらない行数をカウントする
findstr /v /e /c:" " tree.txt | findstr /i \.bak$ | find /v /c ""
tree.txtから.bak(大文字小文字区別なく)で終わらない行数をカウントする

文字列検索:find

使ったオプション

  • /v 文字列にマッチしない行を抜き出す
  • /c 文字列を含む行数をカウントする

記述例

find /v /c "" tree.txt
tree.txtから、空行じゃない行数をカウントする

ディレクトリ、ファイルの存在チェック→なかったらバッチ終了

if not exist ディレクトリ名 (
  echo %1% は存在しません。
  exit /b
)

カレントディレクトリのツリー構造をtree.txtに出力

tree /F > tree.txt

コマンド実行結果を変数に格納

for /f "delims=" %%F in ('実行したいコマンド') do set val=%%F
echo %val%

※実行したいコマンドが、パイプを使っている場合は、パイプを「^|」とエスケープする

echoで空行を出力する

echo:
※echoと:の間にスペースを入れない

カレントディレクトリ以下の.txtファイルを再帰的に処理する

for /r %%i in (*.txt) do (
echo %%i
)

CドライブからDドライブへ移動

cd /d d:\

最後に一言…頼むからCygwin使わせてよ!