Mitsukiの魔法実験室

Mitsuki's Magic Laboratory
Since 2002.09.14

Ruby の hash key は object そのまんま

Posted at 2007/04/10 21:13 in Ruby

404 Blog Not Found:perl|javascript - 文字列じゃないhash key
 JavaScript や Perl の場合ハッシュのキーは文字列限定なので、オブジェクト(Perl はそのリファレンス)をハッシュのキーとして使った場合、ハッシュからキーを取り出したらもはやオブジェクトではなくなってしまう、という話かな(Tie::RefHash なんてあるのね……)。

 Ruby の場合、データはすべてオブジェクトであり、ハッシュは「オブジェクトとオブジェクトを関連付ける入れ物」なので、キーにしたオブジェクトをハッシュから取り出しても元のオブジェクトのまま。そのため、以下のような破廉恥(?)なコードがごく自然に書けてしまう:


input = [ 'hogehoge', 'foooooooo', 'nyoron' ]
reply = { 'hoge' => 'fuga', /fo+o/ => 'bar' }

input.each do |instr|
    reply.each do |key, val|
        puts "#{instr} -> #{val}" if instr[key]
    end
end

 このコードは、配列 input の各文字列に対して、ハッシュ reply のキー(文字列または正規表現オブジェクト)を引数に [] 演算子を適用し、結果が FALSE/nil でなければハッシュの値を表示する。文字列の演算子 [] は、[] の中身が文字列なら普通の比較、正規表現オブジェクトなら正規表現にマッチする文字列を返す(一致・マッチしなければ FALSE/nil を返す)。実行するとこんな感じ:


> ruby test.rb
hogehoge -> fuga
foooooooo -> bar
> 

 ちなみにこれ、最近遊びで書いてる IRC bot "mistral" の自動応答機能の心臓部の抜粋なのだけど、Ruby のこの性質のおかげで、特に工夫するでもなくキーワードに文字列だけでなく正規表現も使えてしまうので便利(キーワード登録時には正規表現であることを明記する I/F は必要だけど)。

Ruby の Struct#values_at に Symbol は使えない?

Posted at 2007/02/23 12:22 in Ruby

 マニュアル読むと Symbol が使えるサンプルがあるのだけど、実際やってみるとエラーになる in 1.8.4 and 5。


#!/usr/bin/env ruby
Foo = Struct.new(:foo, :bar, :baz)
obj = Foo.new('FOO', 'BAR', 'BAZ')
p :bar.to_i
p obj.values_at(0, :bar, 'baz')    # => ["FOO", "BAR", "BAZ"]

とやると


bash-3.2$ ./test.rb
10345
./test.rb:5:in `values_at': offset 10345 too large for struct(size:3) (IndexError) from ./test.rb:5
bash-3.2$

となってしまう。どうも :bar をハンドルに強制変換して範囲エラーになってる気がしてソースを読んでみると(struct.c)、数値と範囲と強制数値変換は実装されているけど、Symbol や 文字列から index を算出するようなコードが見当たらないので、未実装……なのかな??
(どうでもいいけど、Struct の中身って実装レベルだと Array なのね)

Page 2/2: [<] 1 2