2011-08-04 57 views
1

我在Ruby中寫了一個類,其中有實例變量(即@person_summary_info,@name,@dob,@favorite_food)。ruby​​方法應該修改類的實例方法嗎?

爲了解析一段文字,我有一個公開的方法,我從課堂外調用(我們稱之爲interpret)。

該方法調用一些私有類方法,如get_name使用@person_summary_info來提取相應的信息片段(在本例中是人的名字)。如若這些私有方法:

一)使用實例@person_summary_info,或獲得這些信息通過傳遞給他們(參數即get_name VS get_name(person_summary_info)

二)直接修改實例變量和返回任何結果,或修改沒有超出函數範圍,並返回結果(即get_name,設置爲@name = 'John'return 'John')?

這裏的最佳做法是什麼? 謝謝!

+2

你可以重新寫這樣的示例代碼嗎? –

+2

如果您打算提供賞金,那麼您最好儘量讓自己的問題更易於理解。你能否重新寫這個樣本代碼? –

+0

interpret()方法是否意味着是一個setter,它解析傳入的字符串,並相應地設置類的信息? – Brady

回答

1

我已經包含在我的回答底部代碼你的問題我最好的表現,但我想提出我的解決方案,我先了解你的困境......

這樣做,如果你name屬性,就是要公開訪問:如果您name屬性應該ň

class Person 
    attr_accessor :name 

    def initialize(name) 
    @name = name 
    end 

    def interpret(text_to_parse) 
    # I have no idea what you are parsing in real life 
    self.name = text_to_parse.split.last 
    end 
end 

person = Person.new("Frederick") 
puts person.name 
# => "Frederick" 
person.interpret("Please, call me Fred") 
puts person.name 
# => "Fred" 

做到這一點(很容易)公開:(值得一提的是,幾乎任何東西都可以在Ruby中以某種方式訪問​​。 !一的很多事情,讓真棒)

class Person 
    def initialize(name) 
    @name = name 
    end 

    def interpret(text_to_parse) 
    # I have no idea what you are parsing in real life 
    @name = text_to_parse.split.last 
    end 
end 

person = Person.new("Frederick") 
puts person.instance_variable_get("@name") 
# => "Frederick" 
person.interpret("Please, call me Fred") 
puts person.instance_variable_get("@name") 
# => "Fred" 

而且,正如上面提到的,這裏是我最好的你的問題翻譯成代碼:

class Person 
    def initialize 
    @person_summary_info = { name: "foo" } 
    @name = "bar" 
    @dob = "baz" 
    @favorite_food = "beer" 
    end 

    def interpret(text_to_parse) 
    # Some kind of parsing? 
    get_name_1 
    # OR 
    get_name_2(@person_summary_info) 
    # OR 
    get_name_3 
    # OR 
    @name = get_name_4 
    end 

    private 
    def get_name_1 
    @person_summary_info[:name] 
    end 

    def get_name_2(person_summary_info) 
    person_summary_info[:name] 
    end 

    def get_name_3 
    @name = 'John' 
    end 

    def get_name_4 
    'John' 
    end 
end 

希望,你可以看到爲什麼關於你究竟在問什麼的評論中有一些混淆。如果沒有別的,也許看到這會幫助你更清楚地形成你的問題,所以我們可以幫助!

最後,你應該避免用Ruby編寫自己的getter/setter方法,除非你需要一些自定義代碼掛鉤到獲取/設置過程 - 使用類級別attr_reader/attr_writer/attr_accessor宏來創建他們爲你。

1

如果interpret()不是要改變Person的特定實例的狀態,那麼考慮將該方法命名爲get_name_from_string(string),並可能使其成爲靜態的,因爲它不會對該實例的狀態做任何事情。

如果您希望interpret()更改Person的特定實例的狀態,請考慮更改方法的名稱,使用set作爲前綴幷包含正在設置的屬性名稱(set_name_from_string())。如果正在設置幾個屬性,那麼可能是set_from_string()幷包含代碼註釋,指出正在修改哪些實例變量。該方法在內部可以調用get/set_name(),如下所述。

通常情況下,getter/setter方法是公開的,應該是很簡單的,做什麼,他們的名字所暗示的: - getName()返回的實例變量@name - 的setName(name)設置或覆蓋實例變量@name與傳入的值並不返回

在Java中,這是一種POJO,特別是Java Bean(不包括關於需要可序列化的部分)。它在幾種不同語言中具有公共setter/getter方法爲實例變量,並且還有一個默認的構造函數(一個不帶參數)和另一個構造函數允許您在實例化Obj時設置實例變量等。

1

直接從另一個類使用@instance是一種很好的方式如何進入困境。每個類都應該有它自己的變量和任何你想處理或返回迴應該分配/返回,直接..這意味着,方式

@instance = my_class.get_name(person_summary_info) 

,而不是

my_class.get_name 

只是試着去想像如何使用@instance變量測試該代碼並重用該代碼段。

只是我2C