2010-03-12 22 views
3

我正在使用我的MOO項目來教我自己測試驅動設計,它讓我感興趣的地方。例如,我寫了一個測試,說一個特定的對象上的屬性應該總是返回一個數組,所以 -使屬性始終爲數組的最佳方式?

t = Thing.new("test") 
p t.names #-> ["test"] 

t.names = nil 
p t.names #-> [] 

我對這個代碼是好的,但它似乎並不可怕紅寶石給我:

class Thing 

    def initialize(names) 
     self.names = names 
    end 

    def names=(n) 
     n = [] if n.nil? 
     n = [n] unless n.instance_of?(Array) 

     @names = n 
    end 

    attr_reader :names 
end 

有沒有更優雅的Ruby-ish方法來做到這一點?
(注:如果有人想告訴我,爲什麼這是一個愚蠢的測試來寫,這將是有趣的太...)

+0

我有三個很好的答案。感謝大家。 – Shadowfirebird 2010-03-12 13:11:06

+0

如果參數可轉換爲數組會發生什麼? – 2010-03-12 14:19:56

回答

5

我想指出已經有一個內建的方法來做w你想要的帽子!它叫做Array()。問自己的問題是:可轉換爲數組的類會發生什麼(如0..42)?

我覺得大多數Rubyist會希望他們會被轉換。所以:

class Thing 
    attr_accessor :names 

    def initialize(names) 
    self.names = names 
    end 

    def names=(values) 
    @names = Array(values) 
    end 
end 

你會得到相同的結果,例如:

t = Thing.new("car") 
t.names #-> ["car"] 

t.names = nil 
t.names #-> [] 

t.names = 42 
t.names #-> [42] 

t.names = [1, 2, 3] 
t.names #-> [1, 2, 3] 

t.names = 1..3 
t.names #-> [1, 2, 3] # Is this what you want, or not? 
+0

事實上,我不確定它的重要性 - 儘管當然我直到我編寫所有代碼時才肯定知道它! - 但顯然這是最優雅的解決方案。我把勾號轉給了你。對不起,大家。 – Shadowfirebird 2010-03-12 15:45:58

+0

+1,讓我閱讀'Kernel.Array'文檔。 (http://www.ruby-doc.org/core/classes/Kernel.html#M005967) – 2010-03-13 04:08:04

0

使用*獲取數組中的所有PARAMS在你的初始化方法


class Thing 
    attr_accessor :names 

    def initialize(*names) 
     @names = names 
    end 
end 

t = Thing.new("test") 
p t.names #-> ["test"] 

t.names = nil 
p t.names #-> nil 

+0

最後執行返回'nil',而不是'[]' – 2010-03-12 10:44:23

+0

確切的你的權利我建議另一個解決方案 – shingara 2010-03-12 11:02:51

2

您可以使用getter方法來設置值的格式。

class Thing 

    def initialize(names) 
    self.names = names 
    end 

    def names 
    [*@names].compact 
    end 

    def names=(values) 
    @names = values 
    end 

end 

t = Thing.new("test") 
p t.names #-> ["test"] 

t.names = nil 
p t.names #-> [] 
+0

'[* @ names] .compact'真的很好。在我看來,它比'[*(n || [])]'更具可讀性。另外,你是對的:我應該只關心公共方法返回的內容,而不是它如何存儲數據。 – Shadowfirebird 2010-03-12 13:10:00

1

在其他氣味像我以前的答案:


class Thing 
    def initialize(*names)                                                              
    @names = names 
    end 
    def names 
    @names || [] 
    end 
    def names=(*names) 
    @names = names 
    end 
end 

t = Thing.new("test") 
p t.names #-> ["test"] 

t.names = nil 
p t.names #-> [] 
+0

+1,'t.names = nil'後面的代碼將返回'[nil]'給't.names'。您必須爲'names'方法添加一個壓縮文件並刪除'||',因爲'@ names'永遠不會是'nil'。 – 2010-03-12 11:11:31

3

試試這個:

class Thing 

    def initialize(names) 
     self.names = names 
    end 

    def names=(n) 
    @names= [*(n||[])] 
    end 

    attr_reader :names 
end 

讓我們測試類:

t = Thing.new("car") 
t.names #-> ["test"] 

t.names = nil 
t.names #-> [] 

t.names = [1, 2, 3] 
t.names #-> [1, 2, 3] 
+0

我認爲新版本效率很高,它看起來也不錯:-) – 2010-03-12 11:46:23

相關問題