QA@IT
«回答へ戻る

回答を投稿

そのドキュメントに

A Struct is a convenient way to bundle a number of attributes together, using accessor methods, without having to write an explicit class.

とあるように、Structは属性つき匿名クラスを生成するシュガーです。まずこのことを確認しましょう。

> s=Struct.new(:x,:y)
 => #<Class:0x007fc1c18d3418>
> s.class
 => Class

で、ブロックをとるのは、実際にはClassクラスの仕事です。なのでStructクラス自体のドキュメントには言及がないのだと思います。

http://ruby-doc.org/core-1.9.3/Class.html より

fred = Class.new do
  def meth1
    "hello"
  end
  def meth2
    "bye"
  end
end

a = fred.new     #=> #<#<Class:0x100381890>:0x100376b98>
a.meth1          #=> "hello"
a.meth2          #=> "bye"

というわけで、使っても問題なさそうですね。万が一deprecatedの憂き目にあっても、コードの意図は明確ですから、あまり心配いらない気がします。

ついでにいうと、Class.newは継承にも使えるのが結構便利で、

class Error < StandardError; end

Error = Class.new(StandardError)

のように綺麗に(?)書くことができます。

そのドキュメントに

> A Struct is a convenient way to bundle a number of attributes together, using accessor methods, without having to write an explicit class.

とあるように、Structは属性つき匿名クラスを生成するシュガーです。まずこのことを確認しましょう。

```ruby
> s=Struct.new(:x,:y)
 => #<Class:0x007fc1c18d3418>
> s.class
 => Class
```

で、ブロックをとるのは、実際にはClassクラスの仕事です。なのでStructクラス自体のドキュメントには言及がないのだと思います。

http://ruby-doc.org/core-1.9.3/Class.html より

```ruby
fred = Class.new do
  def meth1
    "hello"
  end
  def meth2
    "bye"
  end
end

a = fred.new     #=> #<#<Class:0x100381890>:0x100376b98>
a.meth1          #=> "hello"
a.meth2          #=> "bye"
```

というわけで、使っても問題なさそうですね。万が一deprecatedの憂き目にあっても、コードの意図は明確ですから、あまり心配いらない気がします。

ついでにいうと、`Class.new`は継承にも使えるのが結構便利で、

```ruby
class Error < StandardError; end
```

を

```ruby
Error = Class.new(StandardError)
```

のように綺麗に(?)書くことができます。