2

オブジェクトの新しい getter メソッドを定義したいと考えています。ここに私が書いているコードがありますirb

> eigenclass = class << self; self; end
> eigenclass.class_eval { attr_reader :foo }

このコードは、fooself オブジェクトにメソッドを追加する必要があると思います。しかし、次の行は違うと言います

puts foo  
=> nil
foo = 1
=> 1       #Why is there no exception?
puts foo  
=> 1
puts @foo 
=> nil

何故ですか?

4

2 に答える 2

3

これは、メソッドvar = valを呼び出すのではなく、ローカル変数を割り当てるためです。setter

self.セッター(および同じ名前のローカル変数がある場合は実際のゲッター)を呼び出すには、プレフィックスを付ける必要があります。これにより、予想されるエラーがスローされます。

2.0.0p195 :001 > eigenclass = class << self; self; end
 => #<Class:#<Object:0x007fc6f98e24d0>>
2.0.0p195 :002 > eigenclass.class_eval { attr_reader :foo }
 => nil
2.0.0p195 :003 > foo
 => nil
2.0.0p195 :004 > foo = 20
 => 20
2.0.0p195 :005 > foo
 => 20
2.0.0p195 :006 > self.foo
 => nil
2.0.0p195 :007 > self.foo = 20
NoMethodError: undefined method `foo=' for main:Object
    from (irb):7
于 2013-06-29T10:47:45.667 に答える
3

2 つの間違いを犯しました: a) 完全なアクセサー (ゲッターとセッター) が必要な場合は、次を使用する必要があります。

eigenclass.class_eval { attr_accessor :foo }

b) セッター メソッドを使用する場合は、キーワードを使用する必要がありますself。そうしないと、Ruby がローカル変数を設定します。

self.foo = 1
# => 1
puts @foo
# => 1

または、セッターを定義せずに、インスタンス変数を直接設定できます。

eigenclass.class_eval { attr_accessor :foo }
@foo = 1
puts @foo
# => 1
于 2013-06-29T10:49:37.057 に答える