タイトル長いなw
きっかけ
hash.map.with_indexとかでブロック内に渡すパラメータがどうなるか悩んだことがありまして。
結論
hash.map.with_index do |(key, value), i|
puts "#{i}: #{key} => #{value}"
end
のように 丸括弧 でくくってしまえばOK。
参考
るりまにちゃんと書いてある。
with_index(offset = 0) {|(*args), idx| ... } -> object
[instance method Enumerator#with_index](http://rurema.clear-code.com/1.9.3/method/Enumerator/i/with_index.html)
# いままでやってた書き方
hash.map.with_index do |kv, i|
key, value = kv
puts "#{i}: #{key} => #{value}"
end
いちいちブロック内で別の変数に渡してました。
# 余談
## 名称
まず名称が分からなかったw 「ブロック変数」「ブロックローカル変数」「ブロックパラメータ」…
ですがMatzが「ブロックパラメータ」と書いてるので「ブロックパラメータ」と書きますw
[第6回 Ruby 1.9に起きた変化 - O'Reilly Japan Community Blog](http://www.oreilly.co.jp/community/blog/2009/05/changes-on-ruby-1-9.html)
## ブロックローカル変数宣言
まだ1.9.3を使っているのですが、これ忘れてましたw
ブロック外で使っている変数名をブロックローカルで使うことも出来るんですね。
>ブロックパラメータの後にセミコロンと変数名の列を書くことで,ブロックパラメータ以外にブロックローカルな変数を宣言する機能もあります。
>```
foo = "bear"
# ブロックローカル変数fooを宣言する
3.times do |x; foo|
# ブロックローカル変数fooは毎回nilで初期化される
p foo #=> nil
foo = "dog"
# ブロックの終了毎にブロックローカル変数fooは消える
end
# 外側のローカル変数は変更されない
p foo #=> "bear"
第3回 Ruby1.9の新機能ひとめぐり(中編):洗練された文法と意味論:Ruby Freaks Lounge|gihyo.jp … 技術評論社
つまり
3.times do |x|
foo = nil
p foo
foo = "dog"
end
と同様。いつも、こんな感じで初期化してましたw
外側のローカル変数と同じ変数名をブロックローカル変数として使うことはまずないけれども、宣言だけでブロック冒頭の初期化が不要になるのは少しうれしいです。
そして、この記法はどうやらこの記事が起源らしい(いま知った)。
デフォルトはスコープローカル、明示的に指定した場合だけブロックローカル、 というものを採用する気になった。
- ブロックパラメータの後ろに「;」を置き、そこに続けた変数はブロックローカル変数
ハックしてたら30分でできてしまった。
Matzにっき(2007-01-12)
30分…w