HelloWorld程度ならば、コンパイルツールをつくることは必要ないのでしないのですが、 使えるプログラムというものは、はたくさんのjarをインクルードしたものになりがちです。 標準のコンパイル方法ではクラスパスにJARファイルを追加するのが手作業では、 追加するクラスパスやJARファイルが増えるにしたがって手作業では困難になってきます。 かといって、Mavenをつかってみたんですが無駄な動作をしているし、 Eclipseはコンパイル結果にちょっと癖があって使いづらい。 となれば、自分で簡潔に動作するツールをつくってしまおうとおもったわけです。
フォルダ内の.scalaファイルのタイプスタンプのスナップを取得する。
既存のタイムスタンプと現在のファイルのタイムスタンプを比較し更新されたファイルを取得しコンパイル可能なバッチファイルを生成する
BASEが2回出てきているが、どちらも自動的にJarファイルを読み込みたいフォルダである。下記の例のように追加したいフォルダの数だけ繰り返し記述するとよいでしょう。
@echo off setlocal ENABLEDELAYEDEXPANSION set CP=. set BASE=C:\scala\lib for %%f in (%BASE%\*) do set CP=!CP!;%%f set BASE=C:\scala\lib\user for %%f in (%BASE%\*) do set CP=!CP!;%%f SET SCALA_DOC_HOME="C:\scala\doc" ECHO %CP% scalac -classpath %CP% %1
p Dir::entries("/home/take")
[".", "..", "WorkbookScala.scala"]
p Dir::entries("/home/take")
[".", "..", "WorkbookScala.scala"]
フォルダの区切り文字は\ではなく、/を使うこと
s = File.stat("c:/scala/user/src/WorkbookScala.scala") puts File.mtime(fname).strftime("%Y/%m/%d %H:%M:%S") # 最終更新時刻
c:/scala/user/src/WorkbookScala.scala 2009/12/05 22:16:11
path=ARGV[0].gsub("\\","/") ext="scala" outfile="timestamp.txt" buffer = "" # **は再帰的検索。\0は複数パターンの区切り。.*は隠しファイル取得 Dir.glob("#{path}/**/*\0#{path}/**/.*" + ext).each{|name| puts name buffer = buffer + name + "\n" s = File.stat(name) timestamp = File.mtime(fname).strftime("%Y/%m/%d %H:%M:%S") # 最終更新時刻 puts timestamp buffer = buffer + timestamp + "\n" } # タイムスタンプスナップを上書き更新します。 file = File.open(path + "/" + outfile, "w"); # 書き込む file.write(buffer); file.close
ruby c:\scala\bin\snap_timestamp.rb "c:\scala\user\src"
更新したファイルを出力する
#第一引数はフォルダ名 path=ARGV[0].gsub("\\","/") ext=/.*\.scala$/ outfile="timestamp.txt" current={} # **は再帰的検索。\0は複数パターンの区切り。.*は隠しファイル取得 Dir.glob("#{path}/**/*\0#{path}/**/.*" ).each{|name| if ext =~ name s = File.stat(name) current.store(name,File.mtime(name).strftime("%Y/%m/%d %H:%M:%S")) end } # タイムスタンプ保存用ファイル読み込み before={} file = open(path+"/"+outfile) buffer = file.read().split("\n"); file.close #2行を1つの配列にまとめた配列を作成 newItem="" newItem = nil buffer.each{|line| if newItem == nil newItem=line else if ext =~ newItem before.store(newItem,line) end newItem = nil end } #タイムスタンプの比較 更新・新規追加したファイルを出力 current.each{|filepath, timestamp| if timestamp != before.fetch(filepath) puts filepath end }
ruby snap_timestamp_diff.rb "c:\scala\user\src" > updatelist.txt
RubyをWindowsのDOSで動作させるとRubyからバッチファイルを動作させる際に使用する システムのShellが使用している
のPathの分割処理がバグっているというかcygwinしか想定していないので、 使えません。 動かしてもwindows版rubyにはfork関数が最初から実装されていないっぽい。 つまり複数プロセスの同時実行には対応していない。
別途prototype.jarをつくって、簡単に取得できるようにつくっておきました。
簡潔でしょ?
下記の例は簡潔にかけているんだけど、実際にはInputStream?を閉じないとそのうち不具合がでるので、しっかりとcloseする処理が必要です。
その点上のprototype.jarを使えば、その点が考慮されているばかりか、文字列、配列の基本クラスの拡張までやってくれるので、
開発効率がアップしますよん。
Runtime r = Runtime.getRuntime(); Process p = r.exec("java -version");
Runtime r = Runtime.getRuntime(); Process p = r.exec(new String[] { "C:\\Program Files\\Java\\j2re1.4.2_13\\bin\\java", "-version" });
Runtime r = Runtime.getRuntime(); Process p = r.exec("cmd /c echo zzz"); // Process p = r.exec(new String[]{ "cmd", "/c", "echo", "zzz" });
String[] env = new String[2]; env[0] = "TEST=サンプル"; env[1] = "PATH=" + System.getProperty("java.library.path");
Runtime r = Runtime.getRuntime(); Process p = r.exec("cmd /c echo %TEST%", env);
http://www.ne.jp/asahi/hishidama/home/tech/java/process.html#Runtime
バッチファイルからだと、どういうわけかわかりませんが、1つめのコンパイルが終わるとバッチファイルが終了してしまいます。
startコマンドをつかうと、非同期にコンパイルされてしまい、コンパイルが正しくできない場合があります。 そこで、対策として、SCALAでコンパイルごとにプロセスをたて、なおかつ同期をとりながらコンパイルするコードを作成しました。
import prototype.Prototype._ args(0).read{line :String => ("scalacc " + line).exe }
copy "C:\Documents and Settings\Administrator\workspace\prjPrototype\src\prototype\Prototype.scala" . :CHECK_UPDATE ruby "c:\scala\bin\snap_timestamp_diff.rb" . >updatelist.txt FOR /F %%t IN ('cd') DO SET CURRENTDIR=%%t REM REM scalac "c:\scala\bin\scalacc.scala" %CURRENTDIR% scalac "c:\scala\bin\scalacc.scala"
カレントディレクトリを取得して コマンドに渡しています。
コマンドラインの実行結果を環境変数に格納する方法に
FOR /F %t IN ('TIME /T') DO SET NOWTIME=%t
というサンプルがある。これをDOS窓から実行すると,DOS窓が閉じてしまうのだ。ところが、DOS窓からさらに
cmd
と打ち込んで、もう一段DOS窓をかませて実行すると、DOS窓は閉じなくなるのだ。不思議だ。 バッチファイル実行は、どうなるんだろうか。。。
コマンドの構文が誤っています。
と出てきました。OSはWindowsXPです。 なんでやねん。って言いたいです。
色々サイトをみていたときに、%tではなく%%t表記の表現があることを思い出してバッチファイルを下記のように修正してみました。
FOR /F %%t IN ('TIME /T') DO SET NOWTIME=%%t
画面が閉じる
ただし
cmd
でコマンド画面を1段かませた場合には画面は閉じない
cmd /c バッチファイルという起動方法が良い
Explorer .
さもないと次に示すバッチファイルを2段構えにしたファイルが必要です。
FOR /F %%t IN ('cd') DO SET CDIR=%%t echo %CDIR% Explorer "%CDIR%"
e_for.bat
e (リターン)
DOS画面からファイルを編集したい場合がちょくちょくある。
そこで次のバッチファイルをパスが通ったところに置くと改善する。
start cmd /c "c:\Program Files\sakura\sakura.exe" %1エディタは自分の好みに合わせて変えるといい。
上記のバッチファイルを呼び出す例 フォルダの位置は参考まで
#! /usr/bin/sh /cygdrive/c/userbin/edit.bat "$1"
DOSはなぜかXPになっても石器時代のままだ。できればcygwin環境を標準でつかいたいものだ、zsh、すくなくともbashである。
しかしながらcygwin上からscalaを実行しようとすると下記の問題点があることが判明したので、泣く泣くDOS環境に戻ってつかっているという経緯があったのだ。
cygwin上からscalaを呼び出す際には下記のコマンドで開く
cmd /c start scala
つまり、DOS上かつ別プロセスで実行してやれば問題ないのである。
以上のことから、cygwinのシェルの設定を修正するため .zshrcファイルもしくは.bash_profileに下記の設定を追加しておく
alias scala=cmd /c start scala