2016-10-16 11 views
2

私は新しいRubyistですが、現在は一時オブジェクトを作成するためにStruct inクラスを使用します。メンバの有無による構造体

class A 
    attr_accessor :b 
    B = Struct.new(:name, :print_name) do 
    def print_name 
     p "Hello #{name}" 
    end 
    end 

    def initialize(input_name) 
    @b = B.new(input_name) 
    end 
end 

a = A.new('Leo') 
a.b.print_name # Hello Leo 

しかし、私はまた私の構造体のBのparamsは:print_nameを含まない同じ結果を受信します。私はこのような構造体のメンバを使用する場合しかし、私は質問に遭遇します。

B = Struct.new(:name) do 
... 
end 

だから何が違うのですか?メンバーパララムを使用する必要がありますか? nameprint_name -

あなたは初期化子のクラスを定義する最初のケースで感謝

答えて

3

は2つの引数を取ります。

2番目のケースでは、イニシャライザが単一の引数-を取るクラスを定義します。

これらは、print_nameというインスタンスメソッドを定義しているという事実とは関係ありません。

したがって、両方のクラスのインスタンス(print_name引数の有無にかかわらず)にはprint_nameメソッドが定義されているため、両方の例が同じように機能します。

# first case with two arguments 
B.instance_methods false 
#=> [:name, :name=, :print_name, :print_name=] 

# second case with single argument 
B.instance_methods false 
#=> [:name, :name=, :print_name] 
:また

# first case with two arguments 
foo = B.new(:a, :b) 
foo.inspect 
=> "#<struct B name=:a, print_name=:b>" 

# second case with single argument 
foo = B.new(:a) 
foo.inspect 
=> "#<struct B name=:a>" 

、あなたは両方のケースのためにBクラスのインスタンスメソッドをチェックしますと、あなたは違いを見ることができます:あなたが作成したオブジェクトを検査する際

違いが表示されます

しかし、Struct Bのパラメータがない場合でも同じ結果が表示されます :print_name

違いは、最初のケースでは、あなたが次のことを行うことができるということである。

a.b.print_name = 'new print name' 
a.b.inspect 
#=> "#<struct B name='Leo', print_name='new print name'>" 

後者の場合には、それが失敗するのに対し:

a.b.print_name = 'new print name' 
#=> NoMethodError: undefined method 'print_name=' for #<struct B name='Leo'> 
関連する問題