5 def initialize(arg)
6 @err = false
7 k, @h = nil, Hash.new
8 arg.each{|x| m = /^-(.*)/.match(x); (m) ? (k = m[1].to_sym; @h[k] = nil) : @h[k] ||= x}
9 end
arg は ARGV の値
% .mdiary-run.rb -d 2010-01 -s music
を実行した場合 arg は
arg = ["-d", "2010-01", "-s", "music"]
になる。line 8 はこの配列を
@h = {:d=>"2010-01", :s=>"music"}
のようなハッシュにするためのもの。
arg = ["-d", "2010-01", "-l", "3"] だった場合
@h={:d=>"2010-01", :l=>"3"}
arg = ["-d", "2010-01", "-l"] だった場合
@h={:d=>"2010-01", :l=>nil}
になる。
line 7-8 をくだいて書くと
1 # arg = ["-d", "2010-01", "-s", "music"]
2 k, @h = nil, Hash.new
3 arg.each{|x|
4 m = /^-(.*)/.match(x)
5 if m
6 k = m[1].to_sym
7 @h[k] = nil
8 else
9 @h[k] ||= x
10 end
11 }
line 4: x が '-' で始まっていたら m の値は #<MatchData "-d" 1:"d">
line 5: m の値に何か入っていたら(マッチしたら)
line 6: k に m の1番目のマッチの値を代入。
line 7: ハッシュキーが k で 値が nil のペアを @h に格納。
line 8: m の値に何もはいっていなければ(マッチしなかったら)
line 9: @h[k] が nil の場合は x を代入。@h[k] の値が nil でなく何か値が入っていたら何もしない。
+++ memo +++
1) @h[k] ||= x
line 9 の @h[k] ||= x を @h[k] = x にしてしまうと
あやまって
arg = ["-d", "2010-01", "xxx", "-s", "music"]
が与えられてしまった時
@h = {:d=>"xxx", :s=>"music"}
になってしまう。これでは意図した結果と異なる為 ||= にしている。
2) k = nil
line 2 の k = nil を書き忘れ
line 2 は @h = Hash.new だけだった場合
arg = ["-d", "2010-01", "-s", "music"] を与えると
@h={:d=>nil, nil=>"2010-01", :s=>nil}
になってしまう。
なぜなら...
{} の外側に k が存在していなければ k は {} の中だけで使える変数となり
m == nil でなければ
k = m[1].to_sym なので k には m[1].to_sym が代入されるが
m == nil だった場合、すなわち else 節においては
k = nil が代入されてしまうから。そして
line 9: @h[k] ||= x
で nil を ハッシュキーとしたペア(nil=>"2010-01")を @h に格納することになってしまう。
だから{} の外側の k = nil はとても大切。
外側で定義された k があることによって else 節においても k は m[1].to_sym を保持していてくれる。
[2010-02-26]arg.each{|x| m = /(^-(.*))/.match(x); (m) ? (k = m[2].to_sym; @h[k] = nil) : @h[k] ||= x}
arg.each{|x| m = /^-(.*)/.match(x); (m) ? (k = m[1].to_sym; @h[k] = nil) : @h[k] ||= x}
0 件のコメント:
コメントを投稿