在 Ruby 中的 class 上调用实例方法的原因?

Reason for calling an instance method on a class in Ruby?

我想知道这样做是否有任何特定原因,或者这是某人犯下的愚蠢错误(还是我不理解的其他原因)。

class SomeMailer < ActionMailer::Base
  def first_method(user)
    mail(to: user.email, subject: "Testing")
  end
end

此方法在代码的其他地方被调用如下

SomeMailer.first_method(user).deliver

这就是 rails 的工作方式。 rails 指南中也提到

You never instantiate your mailer class. Rather, you just call the method you defined on the class itself.

Rails 通过调用 method_missin 进行内部处理。 基本上,邮件程序 class 中定义的任何操作方法都将被 method_missing 拦截,并且 return 将成为 MessageDelivery 的实例,否则它将运行默认实现。动作方法从何而来? ActionMailer::Base 继承自 AbstractController::Base,因此它的工作方式与控制器完全相同 - 它 return 是给定 class 的一组 public 实例方法。

Rails 本身鼓励这种行为。想了解更多,可以参考这个link

ActionMailer::Base classes 很奇怪......是的,你确实在 class 上调用实例方法 - 这显然不适用于 'normal' classes!

但是有 some meta-programming magic under the hood:

module ActionMailer
  class Base < AbstractController::Base
    def method_missing(method_name, *args) # :nodoc:
      if action_methods.include?(method_name.to_s)
        MessageDelivery.new(self, method_name, *args)
      else
        super
      end
    end
  end
end

如果您浏览 the rails documentation,您会发现在 class 上调用实例方法对于邮件程序来说是很正常的事情。

我会尝试回答这个问题,因为我自己在处理现有代码时也遇到过类似情况。

当您在 class 上执行 回调 时,class 中的实例方法会有所帮助。例如,如果您想对从 class.

创建的对象执行某些操作

假设您有另一个 class 用户,并且您希望在创建新用户后立即向该用户发送电子邮件。在这种情况下,您可以通过

在该对象上调用此方法

after_save :method_name