2013-03-30 98 views
0

我正在處理「Beginning Ruby」這本書,一切都很順利,直到我得到封裝。我得到了這段代碼正在做的事情,我只是不知道爲什麼它是用這種方法設置的。紅寶石封裝

對於那些有興趣this is the link與書上的封裝頁面。

class Person 
    def initialize(name) 
     set_name(name) 
    end 

    def name 
     @first_name + ' ' + @last_name 
    end 

    def set_name(name) 
     first_name, last_name = name.split(/\s+/) 
     set_first_name(first_name) 
     set_last_name(last_name) 
    end 

    def set_first_name(name) 
     @first_name = name 
    end 

    def set_last_name(name) 
     @last_name = name 
    end 
end 

p = Person.new("Fred Bloggs") 
puts p.name 

在我看來,這樣的事情可以實現相同的:

class Person 
    def initialize(name) 
     @first_name, @last_name = name.split(/\s+/) 
    end 

    def name 
     @first_name + ' ' + @last_name 
    end 
end 

p = Person.new("Fred Bloggs") 
puts p.name 

爲什麼要通過設置在其單獨的方法的對象變量的麻煩?

+2

因爲您正在使用封裝。封裝意味着隔離變量並暴露訪問和修改它們的安全方法。 –

+0

您可以覆蓋to_s方法並避免名爲name的方法,該方法僅用於將該對象表示爲文本。 – kainlite

回答

1

Setter方法可用於修改已存在對象的狀態。在你的案例中,人的名字是「一種」不可變的。你不能改變人的名字,你只能創建一個新名字的新人。

1

在這裏你可以找到類似的解釋 - Classes in Ruby Using Getters and Setters

p RUBY_VERSION 

class Person 
    def initialize(name) 
     set_name(name) 
    end 

    def name 
     @first_name + ' ' + @last_name 
    end 

    def set_name(name) 
     first_name, last_name = name.split(/\s+/) 
     set_first_name(first_name) 
     set_last_name(last_name) 
    end 

    def set_first_name(name) 
     @first_name = name 
    end 

    def set_last_name(name) 
     @last_name = name 
    end 
end 

John = Person.new("Fred Bloggs") 
p John.name # now suppose you misrepresented the last name at time of `John` object creation. Then what would you do? 

John.set_last_name "roy" # this setter method would then help you out to update the last name. 

p John.name 

說明:如果那個人喜歡的對象創建的時候設置一個人的名字,如果有一點錯誤信息,您有在創建時輸入,你不能改變這些。因爲你的代碼的第二部分沒有setter。

輸出:

"2.0.0" 
"Fred Bloggs" 
"Fred roy" 
1

他們幾乎教你getter和setter方法實例變量的最基礎的。假設你想用你編寫代碼的方式來改變變量,你必須直接訪問實例變量。相反,他們創建的方法允許您訪問這些變量,以便您可以在類之外使用它們而不必完全訪問實例變量。

我假設他們將領導到attr_accessorattr_readerattr_writer這就像動態創建您的實例變量存取的宏。

1

假設你有一個像你的用戶名這樣的名字。只有這兩種方法的類在這種情況下不可用,而在原始類中,您只需執行類似如下操作:

Person.new("Stephan").set_last_name("de Vries")