簡體   English   中英

Ruby為什么不自動執行to_s?

[英]Why doesn't Ruby automatically execute 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>

在這種情況下,如果Ruby在string方法之前自動嘗試to_s會更好嗎? 有什么辦法可以得到這種行為?

首先,不,不是。 我不想讓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

(根據需要使用其他方法重復;請注意,這允許您執行類似86.rjust(10) ;這是否是一件好事,可能86.rjust(10)您的口味)

在這種情況下,如果Ruby在string方法之前自動嘗試to_s會更好嗎?

您要求一種語言“在大多數時間里都按照我的意思行事”,這是一條滑坡。 盡管在許多情況下這可能很有意義,但勢必會使邊緣的事情變得骯臟。 在您的情況下,誰說rjust並不是在Author(或其超類之一)上定義的方法。

實際上...有一種方法可以執行與此類似的操作: to_str

但是,在這種情況下仍然不會隱式調用它。 Ruby中存在to_str方法實際上等效於說:“通常將String作為參數的任何方法都可以通過調用to_str方法將該對象隱式轉換為String。” 標准庫中的大多數方法都將嘗試使用此技術來強制轉換為String,許多第三方庫也是如此。

但是,在您給出的示例中,對於Ruby而言,檢測未處理的消息類似於String並進行轉換絕對是不合適的。 這將導致許多與String不相關的代碼中的各種錯誤,錯誤和一般的不當行為,尤其是像Builder這樣依賴正常的方法缺失行為的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM