プログラマメモ2 - programmer no memo2

ネタ Ruby + Groovyって? 2008/05/15

Ruby + Groovyって?

grubyとか思って、検索かけると、
gRuby Project
がでてきました。

他には、gruvyか、gruuvyとかgroobyとか。
無理ありますね。

特定のクラスを格納している JAR ファイルを発見するgroovyスクリプト 2007/08/18


特定のクラスを格納している JAR ファイルを発見するRubyスクリプトを公開している人がいたので、勉強をかねて、groovyにしてみました。

オリジナルのほうはjarコマンドを使用してjarの中のエントリーから見つけ出したいクラスをひっぱてきていましたが、どうせgroovyにするならばというわけで、JarFileクラスを使用してみました。

ちょっと調べきれていないのが、groovyでtoStringしなくてもすむならtoStringしないで文字列で取り扱う方法ですかね。

import java.util.jar.JarFile;

if(this.args.length < 2){
println "Usage: findjar.groovy [classname] [dirname]"
System.exit(0);
}

def classname = args[0]
def dirname = args[1]

classname = classname.replaceAll("¥¥.", "/")

new File(dirname).eachFileMatch(~".*.jar" ){
jarfile ->
new JarFile(jarfile).entries().each({ line ->
if(line.toString().contains(classname)){
println "${jarfile}:${line.toString().replaceAll('/', '¥¥.').replaceFirst('¥¥.class$', '') }";
}
});
}



以下Rubyについてのメモです。
------
rubyのgsubは
gsub(pattern, replace)
らしい。

Dir.glob(pattern)
は、パターンにマッチしたファイルを取得するものらしい。ない場合は空の配列を返す。
パターンにマッチするファイルがない場合は空の配列を返します。

rubyのString#chompは、
文字列の末端の改行を削除します。
逆引きRuby - 文字列
if 文字列.include? other
end
という感じなる。
文字列にそれ含んでる?という問いかけになる感じ。

rubyのinclude?(other) は、
other が範囲内に含まれている時に真を返すらしい。


--
groovyもjava同様、配列の長さをlenghtで、Listの長さはsizeでとれるのですが、
両方でlength,size使えたらうれしいかもしれない。

関連

行列の回転 - zip関数!! groovyでやってみた。 2007/08/14
2007/08/18

ありました。


/*
* function name is renamed!!
* original name is transpose.
* this function original implementation
* http://archive.groovy.codehaus.org/user/46B2E788.8040208%40asert.com.au
*/
def zip(Object[] listOfLists) {
def returnValue = []
if ((listOfLists == null) || (listOfLists.size() == 0))
{return returnValue}
def length = listOfLists.collect {item -&gt; item.size()}.min()
for (i in 0..&lt;length) {
def item = []
for (list in listOfLists) {item &lt;< list[i]}
returnValue &lt;< item
}
returnValue
}

def rotateR90(m){
zip(m[2], m[1], m[0])
}

def m = [ [1, 2, 3],
[4, 5, 6],
[7, 8, 9] ]

println rotateR90(m);


一応できてるっぽい。

実は、全然オリジナルのコードではないです。
Orz...

以下、説明。


他の人の解答をみていて、zipという関数(メソッド?)への言及をみて、はじめわからず調べていきますと、rubyにはzipというのがありました。

self と引数に渡した配列の各要素からなる配列の配列を生成して返します。生成される配列の要素数は self の要素数です。
Rubyリファレンスマニュアル - Enumerable


collectメソッド、mapメソッドは配列の各要素に対してブロックを実行し、結果を配列で返却します。それぞれ、破壊的メソッドcollect!、map!が用意されています。
逆引きRuby - 配列


で、さらに、groovyを調べていきますと、メーリングリストで、
pythonにzip関数があるがgroovyにそれ相当のものがあるかというものでした。
適当にスレッドをおいかけていきますと、
transposeという関数を実装した人がいましてそれを利用してみました。

というわけで、探す労力だけで、全然、脳力を使っていないOrz...

ちなみに、haskellにもありますね。



いい勉強になりました。

groovy injectがよくわからない - rubyのレファレンスを参照 2007/07/22

injectがよくわからないので考えてみる。

rubyのinjectと似ているらしいのでrubyの説明をさがしてみる。

inject([init]) {|result, item| ... } (ruby 1.7 feature)
最初に初期値 init と self の最初の要素を引数にブロックを実行します。2 回目以降のループでは、前のブロックの実行結果と self の次の要素を引数に順次ブロックを実行します。そうして最後の要素まで繰り返し、最後のブロックの実行結果を返します。

要素が空の場合は init を返します。

初期値 init を省略した場合は、最初に先頭の要素と 2 番目の要素をブロックに渡します。この場合、要素が 1 つしかなければブロックを実行せずに最初の要素を返します。要素が空なら nil を返します。Rubyリファレンスマニュアル - Enumerable


Enumerableは、辞書で調べると、【形】 可算{かさん}の とか 帰納的{きのうてき}という意味があります。

えーと
例えば、
[1,2,3,4,5]という配列があって、
[1, 2, 3, 4, 5].inject(0){i, j -> i + j }
と書く場合は、えーと、[1,2,3,4,5]という配列があって、それにinjectという命令をだして、その初期値が0で、
ループ開始は、i の値は、初期値の0,   j は配列の最初の値で、1になって、i + jが次のループの i になる。
イメージしやすくするために、下記のようなコードを実行すると、

println( "result:" + [1,2,3,4,5].inject(0){i, j -> print "(${i} + ${j}) "; i + j })

結果は、
(0 + 1) (1 + 2) (3 + 3) (6 + 4) (10 + 5) result:15

となる。

少しはイメージできるかな。

h-index - 情報食物連鎖末端でgroovy



というのがあった。

単純にコードのうつしかえをしてみようとしたが、Arrayを拡張したような使い方?(なんという仕組みだろう)をgroovyで表現する方法がわからなかったので、それは断念。


class h {
/* static */
static def hiindex (arr){
arr.reverse().inject( 0 ){ result, item -> if(item <= result) return result ; result + 1}
}

static void main(args) {

def h = {
it.reverse().inject( 0 ){ result, item -> if(item <= result) return result ; result + 1 }
}

println( "result:" + [1,2,3,4,5].inject(0){i, j -> print "(${i} + ${j}) "; i + j })
println( [1,2,3,4,5].reverse().inject( 0 ){ result, item -> if(item <= result) return result ; result + 1})
println( [0,10,20,30,40].reverse().inject( 0 ){ result, item -> if(item <= result) return result ; result + 1})
println(hiindex([0,10,20,30,40]))

assert 4 == h([0,10,20,30,40])
assert 4 == h([0,10,20,30,40])
assert 4 == h([10,20,30,40])
assert 3 == h([20,30,40])
assert 2 == h([30,40])
assert 1 == h([40])

assert 3 == h([1,2,3,4,5])
assert 2 == h([1,2,3,4])
assert 2 == h([1,2,3])
assert 1 == h([1,2])
assert 1 == h([1])

assert 3 == h([3,3,3])
assert 2 == h([3,3])
assert 1 == h([3])

assert 0 == h([0,0])
assert 0 == h([0])
assert 0 == h([])

}

}

eclipse プラグイン ルビーでルビルビ Ruby - Eclipse Plugin 2007/07/03
2007/07/16

Dynamic Languages Toolkit

ぼーとしている間に、IDEが動的言語をつぎつぎサポートしていますね。

DLTをためしてみてますが、いい感じですね。
試しているのは、rubyのwindows版とjrubyでなのですが、両方ともプラグインからアクセスして実行できました。Hello Worldしか実行していませんが。。。

たまに実行モジュールへの設定がなくなってしまうのが気になりますが。

他にもeclipse上でRuby用のプラグインがあるようなので試してみたいところです。

現在のアップデートサイトは
http://download.eclipse.org/technology/dltk/updates