2013-03-07 147 views
4

我一直在研究學習一種新的動態腳本語言,用於Web開發,並且在對Python和Ruby感到痛苦之後,我真的很喜歡這兩種,我決定選擇Ruby(它幾乎歸結爲一個投擲硬幣,事實上在英國有比Python/Django更多的RoR工作)。我的問題是關於Ruby中的範圍。我是否必須在方法中聲明一個類屬性才能從其他方法訪問它?Ruby變量範圍

舉例來說,我不能做

class Notes 
    @notes = ["Pick up some milk"] 

    def print_notes 
    puts @notes 
    end 
end 

看來我得聲明我要在構造函數中使用屬性?這個例子的作品:

class Notes 
    def initialize 
    @notes = ["Pick up some milk"] 
    end 

    def print_notes 
    puts @notes 
    end 
end 

這是正確的嗎?我注意到了用@@替代@作爲前綴的例子,但是爲了我的理解,如果類有一個子類(比如Memo),那麼在Notes中對以@@爲前綴的屬性所做的任何更改都會改變Memo中的值?

很抱歉,如果這是一個重複的問題,只是失去了noobie :)

回答

4

在聲明@notes類中而不是在構造函數或實例方法,那麼你正在@notes一個實例變量本類本身的實例。每個班級也都以Class的實例存在。

class Notes 
    @notes = ["Pick up some milk"] 

     def print_notes 
     puts @notes 
     end 
    end 
# => nil 
Notes.instance_variable_get(:"@notes") 
# => ["Pick up some milk"] 

所以答案是肯定的,你需要在構造函數或其他實例方法中聲明實例變量。我想你會喜歡這樣做:

class Notes 
    def notes 
    @notes ||= [] 
    end 

    def print_notes 
    puts @notes 
    end 
end 

note = Notes.new 
note.notes << "Pick up some milk" 
note.notes 
# => ["Pick up some milk"] 

另外:

只要避免類變量如@@notes。改用類實例變量(這是你不知情的做法)。

這樣做:

class Notes 
    def self.notes 
    @notes ||= [] 
    end 
end 

不是這個:

class Notes 
    def notes 
    @@notes ||= [] 
    end 
end 
當你想要一個類變量

。後者會導致你在路上遇到問題。 (但我認爲這是用於不同對話的東西。)

+0

這個(你寫的最後一段代碼片段)和使用'attr_reader','attr_writer'和'attr_accessor'相同嗎?如果是這樣,那是做事情的首選方式嗎? – Iain 2013-03-07 12:27:46

+0

@Iain附加信息之前的最後一個片段?是和不是。是的,它與'attr_reader'相同。不,因爲它定義了一個默認值,而不是'nil',我之所以這樣做是因爲它是一個數組,否則第一次設置它時,你必須使用'note.notes = [「whatever」]''。因爲默認值是一個數組,所以_in practice_和attr_accessor非常相似,因爲你可以操作數值(數組),儘管你不能用'='替換數組。 – iain 2013-03-07 12:38:49

+0

@Iain既然您已經可以編程了,那麼我建議您閱讀「Ruby中的元編程」以獲得廣泛的範圍及其如何影響事物的討論,但互聯網和其他書籍上有很多資源(也許其他人會提出一些)。 – iain 2013-03-07 12:42:23