Struct
構造体を表すクラス。
Struct.new()で構造体クラスを定義する。
code:irb
irb(main):001:0> Hoge = Struct.new(:foo, :bar)
=> Hoge
irb(main):002:0> h = Hoge.new
irb(main):003:0> h.foo
=> nil
irb(main):004:0> h.bar
=> nil
# 定義していないフィールドはエラー
irb(main):005:0> h.lol
NoMethodError (undefined method `lol' for #<struct Hoge foo=nil, bar=nil>) irb(main):006:0> h.foo = "hoge"
=> "hoge"
irb(main):007:0> h.foo
=> "hoge"
# newにブロックを渡すとメソッド定義ができる。
irb(main):022:0> Piyo = Struct.new(:foo, :bar) do
irb(main):023:1* def piyo
irb(main):025:2> end
irb(main):026:1> end
=> Piyo
irb(main):027:0>
irb(main):028:0> p = Piyo.new
irb(main):029:0> p.piyo
=> "piyo: , "
irb(main):030:0> p.foo = "Foo!"
=> "Foo!"
irb(main):032:0> p.bar = "Baaaaaaar!!"
=> "Baaaaaaar!!"
irb(main):033:0> p.piyo
=> "piyo: Foo!, Baaaaaaar!!"
# メソッド定義以外は無理、ブロックのスコープは定義した空間と同じになる。
irb(main):067:0> Klass = Struct.new(:hoge) do
irb(main):068:1* CONSTANT = "定数"
irb(main):069:1> end
=> Klass
irb(main):070:0> Klass.constants
=> :Tms # CONSTANTはこのクラスの定数になってにない。 irb(main):071:0> CONSTANT
=> "定数" # 参照できちゃう
# 無名のまま継承することもできる
# この場合は定義したクラスの親クラスが無名クラスになる。
irb(main):042:0> class Fuga < Struct.new(:x, :y)
irb(main):043:1> def fuga
irb(main):044:2> "x: '#{x}', y: '#{y}'"
irb(main):045:2> end
irb(main):046:1> end
=> :fuga
irb(main):047:0> f = Fuga.new
irb(main):049:0> f.fuga
=> "x: '', y: ''"
irb(main):050:0> f.x = 123
=> 123
irb(main):051:0> f.y = 456
=> 456
irb(main):053:0> f.fuga
=> "x: '123', y: '456'"
# 第一引数に文字列を渡すとそれがクラス名になり、Structクラスのインナークラスとして定義される
irb(main):078:0> Struct.new("Klass", :aa, :bb)
=> Struct::Klass
irb(main):082:0> Struct::Klass.new
=> #<struct Struct::Klass aa=nil, bb=nil> これらが詳しい。