読者です 読者をやめる 読者になる 読者になる

脳汁portal

アメリカ在住(だった)新米エンジニアがその日学んだIT知識を書き綴るブログ

[Ruby]RubyのStructとは何なのか?(構造体?なにそれおいし・・・)

Rubyの組み込みライブラリであるStructの説明です。
http://docs.ruby-lang.org/ja/2.0.0/class/Struct.html

Structとは

  • 構造体クラスらしいです。
    • Classクラスに似た感じですが、Classクラスにさらに情報を付加できるといった感じでしょうか

特徴

①最初からインスタンス変数やそれに伴うattr_accessorメソッドを付加しておくことが出来る
②最初からインスタンスメソッドを付加しておくことが出来る

説明

まずは①の説明

" 構造体の鋳型の作成 "
StructTest = Struct.new("Test", :testval1, :testval2)
p StructTest.class #===> Class

" 鋳型から構造体の作成 "
struct_instance = StructTest.new(10,20)

" 確認 "
puts struct_instance # ===> #<struct Struct::Test testval1=10, testval2=20>
puts struct_instance.testval1  #===> 10
puts struct_instance.testval2  #===> 20

" attr_accessorの確認  "
p struct_instance.methods.find_all{|method| method =~ /testval/}
#===> [:testval1, :testval1=, :testval2, :testval2=]
  • ちなみに1行目のStruct.newの引数の一個目を小文字ではじめると以下のように怒られます。
StructTest = Struct.new("test", :testval1, :testval2)
#> struct.rb:6:in `new': identifier test needs to be constant (NameError)
#>         from struct.rb:6:in `<main>'

クラス名は小文字では始められませんよって言っているので、無名クラスにすれば消えます

StructTest2 = Struct.new(:testval1, :testval2)
p StructTest2.class #===> Class
struct_instance2 = StructTest2.new(30,40)
puts struct_instance2 #===> #<struct StructTest2 testval1=30, testval2=40>

つぎは②の説明

ブロックを渡すことでインスタンスメソッドを構造体に組み込むことが出来ます

" ブロックを渡す "
StructTest3 = Struct.new(:testval1, :testval2) do
  " インスタンスメソッドの定義 "
  def sum
    testval1 + testval2
  end

  def subtraction
    testval1 - testval2
  end
end

" 確認 "
p StructTest3.new(50, 25).sum #===> 75
p StructTest3.new(50, 25).subtraction #===> 25

" 実際にインスタンスメソッドに含まれているか確認 "
p StructTest3.new.methods.find_all{|method| method =~ /sum|subtraction/}
#===> [:sum, :subtraction]