-- / --
--
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

03 / 30
Sun

引っ越しが終わった Ziphil です。

私のプログラムでは、 アイテムなどのデータベースは、 アイテム ID をキーとしたハッシュで管理しています。 そこで、 すべてのデータベースを合わせた 1 つのハッシュを作ろうとして、 hash1 + has2 のように書いたら、 Hash#+ がないと怒られました。 ・・・ないの?

どうやら、 こういう場合は Hash#merge を使うみたいです。 調べてみると、 ただ 2 つのハッシュを混合したハッシュを作るだけでなく、 キーが重複した場合の処理を指定できるみたいです。

hash1 = {:a => 2, :b => 4, :c => 9}
hash2 = {:b => 5, :c => 6, :d => 7}
p hash1.merge(hash2){|key, value1, value2| value1 + value2}    #=> {:a => 2, :b => 9, :c => 15, :d => 7}

次です。 Object#tap というメソッドを知りました。 これは、 self をブロックの引数として評価した後、 self そのものを返すメソッドです。 で、 こんなメソッドが何の役に立つかというと、 メソッドチェーンの途中経過を覗けるんです。

x = [1, 3, 5, 6, 8, 10, 13, 16, 18, 19, 21, 22, 24]
y = x.select(&:even?).map(&:succ)

こんな風に、 配列から偶数だけを取り出して、 それぞれに 1 をたした配列を作りたいとします。

x = [1, 3, 5, 6, 8, 10, 13, 16, 18, 19, 21, 22, 24]
y = x.select(&:even?).tap{|t| p t}.map(&:succ)    # => [6, 8, 10, 16, 18, 22, 24]

こんな感じに途中に tap をはさめば、 select メソッド実行後の途中経過を見ることができるわけです。

デバッグっぽい使い方以外にも、 使い道がありますよ。

x = [2, 5, 8]
p x.inject({}){|h, t| h[t] = t ** 2; h}        # => {2 => 4, 5 => 10, 8 => 16}
p x.inject({}){|h, t| h.tap{h[t] = t ** 2}}    # => {2 => 4, 5 => 10, 8 => 16}

こんな感じに、 配列の各値をキーとして、 その 2 乗を値とするハッシュを作ろうとするわけです。 普通なら 2 行目みたいに inject 使えばいいんですが、 どうも ; h ってのが美しくない。 そこで、 tap の出番です。 多少冗長にはなりますが、 見た目が美しくなります。 効果には個人差があります。

まあ、 何をしているかというと、 破壊的メソッドを実行したときに自分自身が返るようにしているわけです。 要するにかっこつけです。 はい。

とまあ、 Ruby の豆知識でした。

スポンサーサイト

comment ×0
コメント
管理者にだけ表示を許可する
 
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。