2011-08-06 38 views
3
  • 爲什麼叫Foo.setFoo.val回報nil,而不是"foo"
  • 是否有階級評價初始化@val任何機制?
  • 在其範圍@val = "foo"存儲到?紅寶石元編程:初始化變量singleton_class

    class Foo 
        class << self 
        @val = "foo" 
        attr_reader :val 
    
        def set(val) 
         @val = val 
        end 
        end 
    end 
    
    p Foo.val # nil 
    Foo.set("bar") 
    p Foo.val # "bar" 
    

回答

9

可以在富初始化@val這樣的:

class Foo 
    @val = "foo" 
    class << self 
    attr_reader :val 

    def set(val) 
     @val = val 
    end 
    end 
end 

p Foo.val   #=> "foo" 
Foo.set("bar") 
p Foo.val   #=> "bar" 

你的代碼初始化@val不富,但Foo的元類

3

紅寶石一般在分析他們執行的表達式。爲什麼預期你的代碼沒有執行的原因是因爲你設置一個類的實例變量的單類Foo的,但在另一方面,你正在訪問Foo自己的類實例變量,這就是爲什麼它不工作:

class << self 
    @val = "foo" # scope is class scope of singleton class of Foo 
    attr_reader :val 

    def set(val) 
    # scope is instance scope of singleton class of Foo (equal to Foo itself) 
    @val = val 
    end 
end 

這就是爲什麼Foo.val得到你的情況nil - 它尚未設置。

階級的評價設置val可以在維克多已經證明的方式來實現。

this post請參閱有關範圍的討論。

0

無需使用#SET。 簡單定義#val方法並使用nil guard:

class Foo 
    class << self 
     def val; @val ||= "bar" end 
    end 
end 
p Foo.val #=> "bar"