2009-06-13 29 views
0

我有一個作家類:爲什麼Ruby不會自動執行to_s?

class Author < ActiveRecord::Base 
    def to_s 
    name 
    end 
end 

定義to_s允許我做puts Author.first,但不puts Author.first.rjust(10)

NoMethodError: undefined method `rjust' for #<Author:0x21eb5d4> 

,那豈不是更好,如果紅寶石的字符串的方法之前,自動嘗試to_s像這樣的情況?有沒有辦法得到這種行爲?

回答

18

首先,不,它不會。我不想讓ruby在任意對象上說「嘿,也許這是一種字符串方法,讓我看看我是否可以在運行to_s後運行它」。這就是說,有兩種解決方案,你想要做什麼:

如果你想說「在任何Author實例,如果有人調用它沒有的方法,但String確實,那麼它應該神奇叫to_s」,那麼這樣做:

class Author < ActiveRecord::Base 
    def to_s 
    name 
    end 

    def method_missing(s, *a) 
    x = to_s 
    if x.respond_to? s then 
     return x.send(s, *a) 
    else 
     super 
    end 
    end 
end 

如果你想說 「rjust上任何不是一個字符串應該是指調用to_s第一」,則:

class Object 
    def rjust(*a) 
    to_s.rjust(*a) 
    end 
end 

(REPE以期望的其他方法;請注意,這允許您執行諸如86.rjust(10);這是否是一個好事還是壞事可能是口味的問題)

+3

`super.method_missing(s,* a)`不正確。它應該只是`super`,它使用相同的參數來調用超類的方法版本。在Ruby中,super就像一個方法而不是接收者。 – Chuck 2009-06-14 01:21:30

2

豈不是更好,如果紅寶石這樣的情況下該字符串的方法之前,自動嘗試to_s?

通過要求一種語言「只是做我的意思(大部分時間)」,你正走向一個滑坡。雖然在很多情況下它可能是有意義的,但它肯定會讓事情發生在邊緣。在你的情況下,誰又能說rjust不上作者定義(或它的一個父)的方法。

1

其實...有,會做隱約類似於這樣的方法:to_str

但是,它仍然不會被隱式的這種特殊情況下調用。在Ruby中to_str方法的存在,實際上等同於說,「通常會採取一個字符串作爲參數的方法可以隱式調用to_str方法這個對象轉換爲字符串。」標準庫中的大多數方法都會嘗試使用這種技術來強制使用String,並且很多第三方庫也會這樣做。

在你給的例子,但是,它是絕對不合適的Ruby來檢測未處理的消息是弦和轉換。這將導致各種錯誤,錯誤和不當行爲一般在大量的非字符串相關的代碼,尤其是任意的代碼有像生成器,它依賴於正常的失蹤法的行爲。

相關問題