2016-11-01 2 views
1

を更新していない私は、属性のアクセサを持つクラスを持っている:attr_accessor値

class MyClass 
    attr_accessor :a, :b 

    def initialize 
    @a = 1 
    @b = 2 
    end 

    def update_values options 
    a = options[:a] 
    b = options[:b] 
    end 
end 

は私がupdate_valuesabを呼び出した後、その新しい値を保持すべきだと思う:

describe MyClass do 
    before do 
    @thing = MyClass.new 
    end 

    it 'should set a and b' do 
    expect(@thing.a).to eq 1 
    expect(@thing.b).to eq 2 
    @thing.update_values a: 2, b: 5 
    expect(@thing.a).to eq 2 
    expect(@thing.b).to eq 5 
    end 
end 

これは起きていません - テストは失敗します:

Failures: 

    1) MyClass should set a and b 
    Failure/Error: expect(@thing.a).to eq 2 

     expected: 2 
      got: 1 

     (compared using ==) 

属性アクセサーはどのように動作するのでしょうか?私は何が欠けていますか?

答えて

1

ローカル変数abを定義するだけです。

代わりに、インスタンス変数abの新しい値を設定します。今

def update_values options 
    self.a = options[:a] # or @a = options[:a] 
    self.b = options[:b] # or @b = options[:b] 
end 

:ここではあなたがそれを行うことができる方法である

foo = MyClass.new 
#=> #<MyClass:0x007f83eac30300 @a=1, @b=2> 
foo.update_values(a: 2, b: 3) 
foo #=>#<MyClass:0x007f83eac30300 @a=2, @b=3> 
私はattr_accessorがクラスに、A = aとb =メソッドが追加されますので、「自己」の彼らの行動は、暗黙的であろうとすることを考えていた
+0

- しかし、私はそれがRubyを解析するものだと思います。 =代入演算子がメソッド名の=よりも優先されるため。ありがとう! –

+0

Andreyが言っていることに疑問があれば、(元の) 'initialize'の最後に' p "ローカル変数=#{local_variables}"行を追加してください。 'foo = MyClass.new'が呼び出されると、ローカル変数= [:a、:b]" 'が表示されます。 –

関連する問題