为什么';Ruby是否会自动执行?

为什么';Ruby是否会自动执行?,ruby,string,metaprogramming,Ruby,String,Metaprogramming,我有一个作者类: class Author < ActiveRecord::Base def to_s name end end 在这种情况下,如果Ruby在string方法之前自动尝试to_s,不是更好吗?有没有办法让这种行为发生?首先,不,不会。我不希望ruby只是说“嘿,也许这是一个字符串方法,让我看看在对任意对象运行to_s”之后是否可以运行它。也就是说,对于您想要做的事情,有两种解决方案: 如果您想说“在任何作者实例上,如果有人调用它没有的方法,但字符串有,那么

我有一个作者类:

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

在这种情况下,如果Ruby在string方法之前自动尝试
to_s
,不是更好吗?有没有办法让这种行为发生?

首先,不,不会。我不希望ruby只是说“嘿,也许这是一个字符串方法,让我看看在对任意对象运行
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
(根据需要使用其他方法重复;请注意,这允许您执行类似于
86.rjust(10)
;这是否是一件好事可能取决于您的品味)

在这种情况下,如果Ruby自动尝试在string方法之前使用,不是更好吗


如果你要求用一种语言“大部分时间都按我的意思去做”,那你就走下坡路了。虽然在很多情况下这可能是有道理的,但它肯定会把事情弄得一团糟。在您的情况下,谁能说,rjust不是在Author(或其超类之一)上定义的方法呢。。。有一种方法可以做一些与此类似的事情:
to\u str

然而,对于这个特殊的情况,它仍然不会被隐式调用。Ruby中存在的
to_str
方法实际上相当于说,“任何通常以字符串作为参数的方法都可以通过调用
to_str
方法将此对象隐式转换为字符串。”标准库中的大多数方法都会尝试使用此技术强制转换为字符串,很多第三方库也这样做


然而,在您给出的示例中,Ruby检测未处理的消息是类似字符串的并进行转换是绝对不合适的。这将导致许多与字符串无关的代码中出现各种错误、bug和一般错误行为,尤其是像Builder这样依赖于正常缺失方法行为的代码。

请查看ruby的
super。缺失方法(s,*a)
是不正确的。它应该是
super
,它使用相同的参数调用超类版本的方法。在Ruby中,super就像一个方法,而不是一个接收器。@Chuck:谢谢,修正了。在发布之前,我确实测试了我的代码,但是被愚弄了,因为“super”的动作是抛出一个异常——这意味着对于这种特殊情况,错误的语法按预期工作。(因为ruby从未尝试对super的返回值调用“method_missing”)
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
class Object
  def rjust(*a)
    to_s.rjust(*a)
  end
end