そこでStructですよ
「怠慢はプログラマの美徳」というけれど - kなんとかの日記
俺がJavaに萌えない理由を100%代弁してくれている。それはさておき、
data = [ {'name'=>'Foo', 'age'=>20, 'email'=>'foo@mail.com'}, {'name'=>'Bar', 'age'=>21, 'email'=>'bar@mail.net'}, {'name'=>'Baz', 'age'=>22, 'email'=>'baz@mail.org'}, ]
うむ、たしかに冗長だ…
だけど3つくらいならそのまま書くかもしれない。多くなると俺は「怠惰」だからmapとStruct使う。
require 'pp' [ ['Foo', 20, 'foo@mail.com'], ['Bar', 21, 'bar@mail.net'], ['Baz', 22, 'baz@mail.org'], ].map{ |n,a,e| {'name' => n, 'age' => a, 'email' => e} }.tap{|_| pp _} ################ vs ################ Person = Struct.new(:name, :age, :email) [ ['Foo', 20, 'foo@mail.com'], ['Bar', 21, 'bar@mail.net'], ['Baz', 22, 'baz@mail.org'], ].map{ |elms| Person.new(*elms) }.tap{|_| pp _} # >> [{"name"=>"Foo", "age"=>20, "email"=>"foo@mail.com"}, # >> {"name"=>"Bar", "age"=>21, "email"=>"bar@mail.net"}, # >> {"name"=>"Baz", "age"=>22, "email"=>"baz@mail.org"}] # >> [#<struct Person name="Foo", age=20, email="foo@mail.com">, # >> #<struct Person name="Bar", age=21, email="bar@mail.net">, # >> #<struct Person name="Baz", age=22, email="baz@mail.org">]
↑のdataを得たければ前者を、Struct使うなら後者を。
Person = Struct.new :name, :age, :email s = Person.new "Foo", 20, "foo@mail.com" s["name"] # => "Foo" s[:name] # => "Foo" s[0] # => "Foo" s.name # => "Foo"
RubyのStructは萌える。なんせStringでもSymbolでもFixnumでもインデックスにできるし、アクセサにもなる。たまにはStructのことも思い出してあげてください。
ちなみに tap はメソッドチェーンで自分自身に作用させるときに便利。Ruby 1.8でも1.8.7から使えるようになる。
Structとmapであっさり書けるから、わざわざ%hリテラルを導入するには弱いと思う。
追記
こっちのほうがmapがなくていいのかな。Person.newが冗長だって!?
Person = Struct.new(:name, :age, :email) [ Person.new('Foo', 20, 'foo@mail.com'), Person.new('Bar', 21, 'bar@mail.net'), Person.new('Baz', 22, 'baz@mail.org'), ].tap{|_| pp _} # >> [#<struct Person name="Foo", age=20, email="foo@mail.com">, # >> #<struct Person name="Bar", age=21, email="bar@mail.net">, # >> #<struct Person name="Baz", age=22, email="baz@mail.org">]