2010-10-22 35 views
3

在Ruby中,是不是像@foo這樣的實例變量和類變量@@bar在Ruby中,是不是self.user_name與@user_name相同?

在一些代碼,我看到幾個

self.user_name = @name 

甚至

a += 1 if name != user_name # this time, without the "self." 
           # and it is the first line of a method so 
           # it doesn't look like it is a local variable 

什麼是自我?我認爲它可能是一個訪問器,但不能只是user_name而不是self.user_name?我什至沒有看到任何代碼,使其成爲一個訪問器,如attr_accessor,而不是在基類中。

+0

其他答案給出了範圍,實例變量和局部範圍變量的一個好主意。閱讀這些問題是爲了對問題有一個很好的理解,他們遺漏的一件事就是'self'是對當前'範圍'的引用,當在一個實例中使用時,其他編程語言中'this'的ruby等價物方法,它引用當前實例,當在類方法中使用時,它引用該類。 – Jeremy 2010-10-22 11:30:57

回答

-1

歡迎在「範圍」地獄!

當然,如果我們有完整的代碼,應該更容易解釋你所看到的。

讓我試試:

 
class Woot 
    attr_accessor :name 

    def initialize 
    self.name = 'Bistromathic Drive' 
    end 

    def foo 
    puts name # hum… I don't know name. An attr? Oh Yes! 
    name = '42' # New local var named 'name' 
    puts name # Yeah! I know a local named 'name' 
    puts self.name # I know the attr named 'name' 
    name = 'Improbability Drive' # Change the local 
    puts name 
    puts self.name # attr didn't move 
    self.name = 'What was the question?' 
    puts name 
    puts self.name 
    end 
end 
w = Woot.new 
w.foo 
# => Bistromathic Drive 
42 
Bistromathic Drive 
Improbability Drive 
Bistromathic Drive 
Improbability Drive 
What was the question? 

你展示的是「懷疑」對我來說,我更願意解釋VAR範圍的底部的部分代碼。

4

在Ruby:

  • @foo是可變的
  • @@bar一個實例是一個類變量

實例和類變量默認爲私密。這意味着,您無法在課程或模塊本身之外設置或獲取該值。

如果要爲foo設置值,則需要一個屬性存取器。

class Model 
    def foo 
    @foo 
    end 

    def foo=(value) 
    @foo = value 
    end 
end 

爲了方便(和性能的原因),這是相同的

class Model 
    attr_accessor :foo 
end 

然後,你可以做

m = Model.new 
m.foo = "value" 

和類中,你可以鬥

class Model 

    # ... 

    def something 
    self.foo = "value" 
    # equivalent to 
    @foo = value 
    end 

end 
1

什麼是自我?我認爲這可能是一個訪問者

這是一個方法至少 - 可能是一個訪問者。 self.name = something將調用方法name=self.name,或者如果沒有稱爲name的本地變量存在,則只需name將調用方法name

但後來不能只是user_name而不是self.user_name?

當調用name=方法,你需要的self因爲name = something只想創建一個名爲name一個局部變量。當調用name方法時,不管你是寫name還是self.name,除非還有一個局部變量name

我甚至沒有看到任何代碼使它成爲訪問器,比如attr_accessor,而不是在基類中。

如果有attr_accessor沒有呼叫和namename=沒有明確的定義,任何地方,他們可能會被method_missing處理或超過attr_accessor不同的方法來定義。

只有當它的定義是不self.user_name一樣@user_name

。如果您定義了user_nameuser_name=? using attr_accessor they will get and set @ user_name`。但是,如果您通過其他方式(或手動)定義它們,則可以執行任何您想要的操作。

例如ActiveRecord使用method_missing來「定義」與數據庫列對應的getter和setter方法。因此,如果您的ActiveRecord類屬於包含user_name列的表,則您將有user_nameuser_name=方法,而無需在任何地方定義它們。由user_name返回並由user_name =設置的值也將不對應於實例變量。即將不會有名爲@user_name的實例變量。

另一種方式來自動定義user_nameuser_name=不使用實例變量是Struct

MyClass = Struct.new(:user_name) 

這裏MyClass將有方法user_nameuser_name=,但沒有實例變量@user_name將在任何時候進行設置。

相關問題