# Struct

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

## スーパークラス:

- Object

## インクルードしているモジュール:

- Enumerable

## クラスメソッド:

`Struct.new([name,] member ... )`

  `Struct` クラスに name という名前の新しいサブクラスを作っ て、それを返します。サブクラスでは構造体のメンバに対するアクセスメ ソッドが定義されています。例えば:

      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"` を出力します。

  構造体名 name はStructのクラス定数名になりますので大文字で始 まる必要があります。member は、Symbol か文字列で指定し ます。

  第一引数が文字列の場合、クラス名として扱おうとするため以下のような 指定はエラーになります。したがってメンバは Symbol を指定する のが無難です*1

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

  name を省略した場合(第一引数が Symbol の場合)、生成し た構造体クラスは名前のないクラスとなります。名前のないクラスは、最 初に名前を求める際に代入されている定数名を検索し、見つかった定数名 をクラス名とします(Class.newを参照)。

  例: 構造体クラスのクラス名

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

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

## 構造体クラスのクラスメソッド:

`Struct::XXX.new(value,...)`
`Struct::XXX[value,...]`

  構造体オブジェクトを生成して返します。引数は構造体の初期値です。構 造体のメンバの数よりも多く指定するとと 例外 ArgumentError が 発生します。メンバの初期値は指定されなければ `nil` です。

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

`Struct::XXX.members`

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

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

## メソッド:

`self[nth]`

  構造体の nth 番目のメンバの値を返します。nth が文字列 または Symbol の場合はその名前のメンバの値を返します。

  存在しないメンバを指定した場合、例外 IndexError あるいは NameError が発生します。

      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)

`self[nth]=value`

  構造体の nth 番目のメンバの値を value にして value を返します。nth が文字列または Symbol の場 合はその名前のメンバの値を value にします。

  存在しないメンバを指定した場合、例外 IndexError あるいは NameError が発生します。

`each {|value| ... }`

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

  `self` を返します。

`each_pair {|member, value| ... } ((<ruby 1.7 feature>))`

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

  `self` を返します。

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

      # => [:foo, "FOO"]
           [:bar, "BAR"]

`length`
`size`

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

`members`

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

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

`values`
`to_a`

  構造体のメンバの値を配列にいれて返します。例えば以下のようにして passwd のエントリ(etc.so 参照)を出力できます。

      require 'etc'
      print Etc.getpwuid.values.join(":"), "\n"

`values_at(member_1, ... member_n)`

  ruby 1.8 feature

  引数で指定されたメンバ(数値、文字列あるいは Symbol)の値の配 列を返します。存在しないメンバを指定した場合は例外 IndexError あるいは NameError が発生します。

      Foo = Struct.new(:foo, :bar, :baz)
      obj = Foo.new('FOO', 'BAR', 'BAZ')

      p obj.values_at(0, :bar, 'baz')    # => ["FOO", "BAR", "BAZ"]

*1 実装の都合により、クラス名の省略は後づけの機能でし た。メンバ名に文字列を指定できるのは後方互換性のためだと考えた方が 良いでしょう

links: [ArgumentError] [Class] [Enumerable] [IndexError] [NameError] [Object] [Symbol] [etc.so] [ruby 1.8 feature]
reverse links: [1.6.8から1.8.0への変更点(まとめ)] [Process] [Ruby用語集] [Time] [ruby 1.6 feature] [ruby 1.7 feature] [ruby 1.8 feature] [機能別索引] [組み込みクラス／モジュール／例外クラス]