2010-02-25 110 views
2

當我從數據庫表中檢索數據時,會填充一個數組。一些字段被定義爲十進制&貨幣字段,並在數組內表示爲BigDecimal。覆蓋Ruby中的BigDecimal to_s默認值

我使用這些數組值來填充CSV文件,但問題是所有BigDecimal值默認都以科學格式表示(這是BigDecimal to_s方法的默認行爲)。我可以使用to_s('F')顯示值,但是我怎樣才能覆蓋默認?

回答

2

這是建立在@法雷爾的答案,但沒有與無用old_xyz方法污染的方法命名空間。另外,爲什麼不直接使用默認參數?

class BigDecimal 
    old_to_s = instance_method :to_s 

    define_method :to_s do |param='F'| 
    old_to_s.bind(self).(param) 
    end 
end 

在Ruby 1.8,這得到略微醜陋:

class BigDecimal 
    old_to_s = instance_method :to_s 

    define_method :to_s do |param| 
    old_to_s.bind(self).call(param || 'F') 
    end 
end 

或者,如果你不喜歡你與上面的代碼得到警告:

class BigDecimal 
    old_to_s = instance_method :to_s 

    define_method :to_s do |*param| 
    old_to_s.bind(self).call(param.first || 'F') 
    end 
end 
+0

嘗試了這段代碼,但得到了「語法錯誤,意外的'=',期待tCOLON2或'['或'。'在define_method行 – Skoppensboer 2010-03-12 06:29:00

+0

@Skoppensboer:帶有默認參數塊的可選參數是一個Ruby 1.9特性,就像'block。(foo)'語法一樣,在Ruby 1.8中你必須使用不同的解決方案來提供默認參數,需要使用'call'方法 – 2010-03-12 14:08:49

+0

Thx Joerg,認爲可能是這樣,但我想幫助的人仍然在1.8.7 – Skoppensboer 2010-03-15 07:09:33

0

Ruby使這個很簡單。看:

class BigDecimal 
    def to_s 
    return "Whatever weird format you want" 
    end 
end 

# Now BigDecimal#to_s will do something new, for all BigDecimal objects everywhere. 

這種技術被稱爲猴子修補。正如你可能從名字中猜出的那樣,你應該謹慎使用。不過,這種使用對我來說似乎很合理。

1
class BigDecimal 
    alias old_to_s to_s 

    def to_s(param = nil) 
     self.old_to_s(param || 'F') 
    end 
end 
+0

輝煌!感謝法雷爾和大衛,我知道這應該是可能的,只是不知道該怎麼做。 – Skoppensboer 2010-02-26 06:24:14

+0

請不要這樣做。它不必要地用'old_to_s'方法污染'BigDecimal'的命名空間。 – 2010-02-26 11:37:38