class Struct

[edit]

要約

構造体クラス。Struct.new はこのクラスのサブクラスを新たに生成します。

個々の構造体はサブクラスから Struct.new を使って生成します。個々の構造体サブクラスでは構造体のメンバに対するアクセスメソッドが定義されています。

目次

特異メソッド
インスタンスメソッド

継承しているメソッド

Enumerableから継承しているメソッド

特異メソッド

new(*args, keyword_init: nil) -> Class[permalink][rdoc][edit]
new(*args, keyword_init: nil) {|subclass| block } -> Class

Struct クラスに新しいサブクラスを作って、それを返します。

サブクラスでは構造体のメンバに対するアクセスメソッドが定義されています。



dog = Struct.new("Dog", :name, :age)
fred = dog.new("fred", 5)
fred.age = 6
printf "name:%s age:%d", fred.name, fred.age
#=> "name:fred age:6" を出力します

実装の都合により、クラス名の省略は後づけの機能でした。メンバ名に String を指定できるのは後方互換性のためだと考えた方が良いでしょう。したがって、メンバ名は Symbol で指定するのが無難です。

[PARAM] args:
構造体を定義するための可変長引数。String または Symbol を指定します。
[PARAM] keyword_init:
構造体クラスのインスタンスを生成する際に、キーワード引数を使用するかどうかを指定します。値の意味は次のとおりです。
  • nil: キーワード引数と位置引数のどちらを使用してもよい
  • true: キーワード引数のみ使用できる
  • false: キーワード引数は使用できず、位置引数のみ使用できる


Point1 = Struct.new(:x, :y)
Point1.new(1, 2)             # => #<struct Point1 x=1, y=2>
Point1.new(x: 1, y: 2)       # => #<struct Point1 x=1, y=2>
Point1.new(x: 1)             # => #<struct Point1 x=1, y=nil>
Point1.new(y: 2)             # => #<struct Point1 x=nil, y=2>
Point1.new(x: 1, y: 2, z: 3) # => ArgumentError (unknown keywords: z)

Point2 = Struct.new(:x, :y, keyword_init: nil)
Point2.new(1, 2)             # => #<struct Point2 x=1, y=2>
Point2.new(x: 1, y: 2)       # => #<struct Point2 x=1, y=2>
Point2.new(x: 1)             # => #<struct Point2 x=1, y=nil>
Point2.new(y: 2)             # => #<struct Point2 x=nil, y=2>
Point2.new(x: 1, y: 2, z: 3) # => ArgumentError (unknown keywords: z)

Point3 = Struct.new(:x, :y, keyword_init: true)
Point3.new(1, 2)             # => wrong number of arguments (given 2, expected 0) (ArgumentError)
Point3.new(x: 1, y: 2)       # => #<struct Point3 x=1, y=2>
Point3.new(x: 1)             # => #<struct Point3 x=1, y=nil>
Point3.new(y: 2)             # => #<struct Point3 x=nil, y=2>
Point3.new(x: 1, y: 2, z: 3) # => ArgumentError (unknown keywords: z)

Point4 = Struct.new(:x, :y, keyword_init: false)
Point4.new(1, 2)             # => #<struct Point4 x=1, y=2>
Point4.new(x: 1, y: 2)       # => #<struct Point4 x={:x=>1, :y=>2}, y=nil>
                             # これは Point4.new({x: 1, y: 2}) とみなされていることに注意
Point4.new(x: 1)             # => #<struct Point4 x={:x=>1}, y=nil>
Point4.new(y: 2)             # => #<struct Point4 x={:y=>2}, y=nil>
Point4.new(x: 1, y: 2, z: 3) # => #<struct Point4 x={:x=>1, :y=>2, :z=>3}, y=nil>

第一引数が String の場合

args[0] が String の場合、クラス名になるので、大文字で始まる必要があります。つまり、以下のような指定はエラーになります。



p Struct.new('foo', 'bar')
# => -:1:in `new': identifier foo needs to be constant (NameError)

また args[1..-1] は、SymbolString で指定します。



p Struct.new("Foo", :foo, :bar)   # => Struct::Foo

第一引数が Symbol の場合

args[0] が Symbol の場合、生成した構造体クラスは名前の無いクラスになります。名前の無いクラスは最初に名前を求める際に代入されている定数名を検索し、見つかった定数名をクラス名とします。



Foo = Struct.new(:foo, :bar)
p Foo                             # => Foo

ブロックを指定した場合

Struct.new にブロックを指定した場合は定義した Struct をコンテキストにブロックを評価します。また、定義した Struct はブロックパラメータにも渡されます。



Customer = Struct.new(:name, :address) do
  def greeting
    "Hello #{name}!"
  end
end
Customer.new("Dave", "123 Main").greeting # => "Hello Dave!"

Structをカスタマイズする場合はこの方法が推奨されます。無名クラスのサブクラスを作成する方法でカスタマイズする場合は無名クラスが使用されなくなってしまうことがあるためです。

[SEE_ALSO] Class.new

new(*args) -> Struct[permalink][rdoc][edit]
self[*args] -> Struct

(このメソッドは Struct の下位クラスにのみ定義されています) 構造体オブジェクトを生成して返します。

[PARAM] args:
構造体の初期値を指定します。メンバの初期値は指定されなければ nil です。
[RETURN]
構造体クラスのインスタンス。
[EXCEPTION] ArgumentError:
構造体のメンバの数よりも多くの引数を指定した場合に発生します。


Foo = Struct.new(:foo, :bar)
foo = Foo.new(1)
p foo.values      # => [1, nil]
keyword_init? -> bool | nil[permalink][rdoc][edit]

(このメソッドは Struct の下位クラスにのみ定義されています) 構造体が作成されたときに keyword_init: true を指定されていたら true を返します。 false を指定されていたら false を返します。それ以外の場合は nil を返します。



Foo = Struct.new(:a)
Foo.keyword_init? # => nil
Bar = Struct.new(:a, keyword_init: true)
Bar.keyword_init? # => true
Baz = Struct.new(:a, keyword_init: false)
Baz.keyword_init? # => false
members -> [Symbol][permalink][rdoc][edit]

(このメソッドは Struct の下位クラスにのみ定義されています) 構造体のメンバの名前(Symbol)の配列を返します。



Foo = Struct.new(:foo, :bar)
p Foo.members      # => [:foo, :bar]

インスタンスメソッド

self == other -> bool[permalink][rdoc][edit]

self と other のクラスが同じであり、各メンバが == メソッドで比較して等しい場合に true を返します。そうでない場合に false を返します。

[PARAM] other:
self と比較したいオブジェクトを指定します。


Dog = Struct.new(:name, :age)
dog1 = Dog.new("fred", 5)
dog2 = Dog.new("fred", 5)

p dog1 == dog2                #=> true
p dog1.eql?(dog2)             #=> true
p dog1.equal?(dog2)           #=> false

[注意] 本メソッドの記述は Struct の下位クラスのインスタンスに対して呼び出す事を想定しています。Struct.new は Struct の下位クラスを作成する点に注意してください。

[SEE_ALSO] Struct#eql?

self[member] -> object[permalink][rdoc][edit]

構造体のメンバの値を返します。

[PARAM] member:
Integer でメンバのインデックスを指定します。 Symbol, String でメンバの名前を指定します。
[EXCEPTION] IndexError:
member が整数で存在しないメンバを指定した場合に発生します。
[EXCEPTION] NameError:
member が String, Symbol で存在しないメンバを指定した場合に発生します。


Foo = Struct.new(:foo, :bar)
obj = Foo.new('FOO', 'BAR')
p obj[:foo]     # => "FOO"
p obj['bar']    # => "BAR"
# p obj[:baz]     # => in `[]': no member 'baz' in struct (NameError)
p obj[0]        # => "FOO"
p obj[1]        # => "BAR"
p obj[-1]       # => "BAR"    # Array のように負のインデックスも指定できます。
p obj[2]        # => in `[]': offset 2 too large for struct(size:2) (IndexError)

[注意] 本メソッドの記述は Struct の下位クラスのインスタンスに対して呼び出す事を想定しています。Struct.new は Struct の下位クラスを作成する点に注意してください。

self[member] = value[permalink][rdoc][edit]

構造体の member で指定されたメンバの値を value にして value を返します。

[PARAM] member:
Integer でメンバのインデックスを指定します。 Symbol, String でメンバの名前を指定します。
[PARAM] value:
メンバに設定する値を指定します。
[EXCEPTION] IndexError:
member が整数で存在しないメンバを指定した場合に発生します。
[EXCEPTION] NameError:
member が String, Symbol で存在しないメンバを指定した場合に発生します。

[注意] 本メソッドの記述は Struct の下位クラスのインスタンスに対して呼び出す事を想定しています。Struct.new は Struct の下位クラスを作成する点に注意してください。



Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)

joe["name"] = "Luke"
joe[:zip]   = "90210"

joe.name   #=> "Luke"
joe.zip    #=> "90210"
values -> [object][permalink][rdoc][edit]
to_a -> [object]
deconstruct -> [object]

構造体のメンバの値を配列にいれて返します。



Customer = Struct.new(:name, :address, :zip)
Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345).to_a
# => ["Joe Smith", "123 Maple, Anytown NC", 12345]

[注意] 本メソッドの記述は Struct の下位クラスのインスタンスに対して呼び出す事を想定しています。Struct.new は Struct の下位クラスを作成する点に注意してください。

[SEE_ALSO] パターンマッチ/非プリミティブなオブジェクトのマッチ: deconstruct メソッドと deconstruct_keys メソッド

deconstruct_keys(array_of_names) -> Hash[permalink][rdoc][edit]

self のメンバの名前と値の組を Hash で返します。

[PARAM] array_of_names:
返り値に含めるメンバの名前の配列を指定します。nil の場合は全てのメンバを意味します。


Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
h = joe.deconstruct_keys([:zip, :address])
h # => {:zip=>12345, :address=>"123 Maple, Anytown NC"}

# 引数が nil の場合は全てのメンバを返します。
h = joe.deconstruct_keys(nil)
h # => {:name=>"Joseph Smith, Jr.", :address=>"123 Maple, Anytown NC", :zip=>12345}

[注意] 本メソッドの記述は Struct の下位クラスのインスタンスに対して呼び出す事を想定しています。Struct.new は Struct の下位クラスを作成する点に注意してください。

[SEE_ALSO] パターンマッチ/非プリミティブなオブジェクトのマッチ: deconstruct メソッドと deconstruct_keys メソッド

dig(key, ...) -> object | nil[permalink][rdoc][edit]

self 以下のネストしたオブジェクトを dig メソッドで再帰的に参照して返します。途中のオブジェクトが nil であった場合は nil を返します。

[PARAM] key:
キーを任意個指定します。


klass = Struct.new(:a)
o = klass.new(klass.new({b: [1, 2, 3]}))

o.dig(:a, :a, :b, 0)              # => 1
o.dig(:b, 0)                      # => nil

[SEE_ALSO] Array#dig, Hash#dig, OpenStruct#dig

each {|value| ... } -> self[permalink][rdoc][edit]
each -> Enumerator

構造体の各メンバに対して繰り返します。

[注意] 本メソッドの記述は Struct の下位クラスのインスタンスに対して呼び出す事を想定しています。Struct.new は Struct の下位クラスを作成する点に注意してください。



Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.each {|x| puts(x) }

# => Joe Smith
#    123 Maple, Anytown NC
#    12345
each_pair {|member, value| ... } -> self[permalink][rdoc][edit]
each_pair -> Enumerator

構造体のメンバ名(Symbol)と値の組を引数にブロックを繰り返し実行します。



Foo = Struct.new(:foo, :bar)
Foo.new('FOO', 'BAR').each_pair {|m, v| p [m,v]}
# => [:foo, "FOO"]
#    [:bar, "BAR"]

[注意] 本メソッドの記述は Struct の下位クラスのインスタンスに対して呼び出す事を想定しています。Struct.new は Struct の下位クラスを作成する点に注意してください。

eql?(other) -> bool[permalink][rdoc][edit]

self と other のクラスが同じであり、各メンバが eql? メソッドで比較して等しい場合に true を返します。そうでない場合に false を返します。

[PARAM] other:
self と比較したいオブジェクトを指定します。


Dog = Struct.new(:name, :age)
dog1 = Dog.new("fred", 5)
dog2 = Dog.new("fred", 5)

p dog1 == dog2                #=> true
p dog1.eql?(dog2)             #=> true
p dog1.equal?(dog2)           #=> false

[注意] 本メソッドの記述は Struct の下位クラスのインスタンスに対して呼び出す事を想定しています。Struct.new は Struct の下位クラスを作成する点に注意してください。

[SEE_ALSO] Struct#==

equal?(other) -> bool[permalink][rdoc][edit]

指定された other が self 自身である場合のみ真を返します。これは Object クラスで定義されたデフォルトの動作です。

[注意] 本メソッドの記述は Struct の下位クラスのインスタンスに対して呼び出す事を想定しています。Struct.new は Struct の下位クラスを作成する点に注意してください。

[SEE_ALSO] Struct#eql?, Struct#==

select {|i| ... } -> [object][permalink][rdoc][edit]
select -> Enumerator
filter {|i| ... } -> [object]
filter -> Enumerator

構造体のメンバの値に対してブロックを評価した値が真であった要素を全て含む配列を返します。真になる要素がひとつもなかった場合は空の配列を返します。

ブロックを省略した場合は Enumerator を返します。



Lots = Struct.new(:a, :b, :c, :d, :e, :f)
l = Lots.new(11, 22, 33, 44, 55, 66)
l.select {|v| (v % 2).zero? }   #=> [22, 44, 66]

[注意] 本メソッドの記述は Struct の下位クラスのインスタンスに対して呼び出す事を想定しています。Struct.new は Struct の下位クラスを作成する点に注意してください。

[SEE_ALSO] Enumerable#select

hash -> Integer[permalink][rdoc][edit]

self が保持するメンバのハッシュ値を元にして算出した整数を返します。 self が保持するメンバの値が変化すればこのメソッドが返す値も変化します。



Dog = Struct.new(:name, :age)
dog = Dog.new("fred", 5)
p dog.hash                    #=> 7917421
dog.name = "john"
p dog.hash                    #=> -38913223

[注意] 本メソッドの記述は Struct の下位クラスのインスタンスに対して呼び出す事を想定しています。Struct.new は Struct の下位クラスを作成する点に注意してください。

inspect -> String[permalink][rdoc][edit]
to_s -> String

self の内容を人間に読みやすい文字列にして返します。

[注意] 本メソッドの記述は Struct の下位クラスのインスタンスに対して呼び出す事を想定しています。Struct.new は Struct の下位クラスを作成する点に注意してください。



Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.inspect # => "#<struct Customer name=\"Joe Smith\", address=\"123 Maple, Anytown NC\", zip=12345>"
length -> Integer[permalink][rdoc][edit]
size -> Integer

構造体のメンバの数を返します。

[注意] 本メソッドの記述は Struct の下位クラスのインスタンスに対して呼び出す事を想定しています。Struct.new は Struct の下位クラスを作成する点に注意してください。



Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.length   #=> 3
members -> [Symbol][permalink][rdoc][edit]

構造体のメンバの名前(Symbol)の配列を返します。



Foo = Struct.new(:foo, :bar)
p Foo.new.members  # => [:foo, :bar]

[注意] 本メソッドの記述は Struct の下位クラスのインスタンスに対して呼び出す事を想定しています。Struct.new は Struct の下位クラスを作成する点に注意してください。

to_h -> Hash[permalink][rdoc][edit]
to_h {|member, value| block } -> Hash

self のメンバ名(Symbol)と値の組を Hash にして返します。



Customer = Struct.new(:name, :address, :zip)
Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345).to_h
# => {:name=>"Joe Smith", :address=>"123 Maple, Anytown NC", :zip=>12345}

ブロックを指定すると各ペアでブロックを呼び出し、その結果をペアとして使います。

ブロック付きの例

Customer = Struct.new(:name, :address, :zip)
Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345).to_h {|member, value|
  [member, value*2]
} # => {:name=>"Joe SmithJoe Smith", :address=>"123 Maple, Anytown NC123 Maple, Anytown NC", :zip=>24690}

[注意] 本メソッドの記述は Struct の下位クラスのインスタンスに対して呼び出す事を想定しています。Struct.new は Struct の下位クラスを作成する点に注意してください。

values_at(*members) -> [object][permalink][rdoc][edit]

引数で指定されたメンバの値の配列を返します。

[PARAM] members:
IntegerRange でメンバのインデックスを指定します。
[EXCEPTION] IndexError:
member が整数で存在しないメンバを指定した場合に発生します。


Foo = Struct.new(:foo, :bar, :baz)
obj = Foo.new('FOO', 'BAR', 'BAZ')
p obj.values_at(0, 1, 2)    # => ["FOO", "BAR", "BAZ"]

[注意] 本メソッドの記述は Struct の下位クラスのインスタンスに対して呼び出す事を想定しています。Struct.new は Struct の下位クラスを作成する点に注意してください。