Ruby类与实例方法的混淆

Mar*_*olz 3 ruby ruby-on-rails learn-ruby-on-rails

鉴于课程:

class UserMailer < ActionMailer::Base
  default from: "do-not-reply@mark.com"
  def contact_email(contact)
    @contact = contact
    mail(to: 'm@mark.com', from: @contact.email, subject: "Website Contact")
  end
end
Run Code Online (Sandbox Code Playgroud)

以及以下测试代码:

c = Contact.new
UserMailer.contact_email(c)
Run Code Online (Sandbox Code Playgroud)

这段代码是如何工作的?我认为我的contact_email是一个实例方法,但它作为一个类方法被调用,并且它可以工作.

感谢您的帮助 - 我学习Ruby和Rails :)

-标记

Fre*_*ung 5

乍一看,这看起来是错误的,这是完全正确的.

它的工作原理是因为method_missing 类(见源代码)看起来像这样

  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
Run Code Online (Sandbox Code Playgroud)

action_methods基本上是邮件程序的名称,对应于可以发送的电子邮件,并且MessageDelivery是一个最终会做的小代理类

YourMailer.new.send(:contact_mailer, ...)
Run Code Online (Sandbox Code Playgroud)

在我的脑海中,我不完全确定为什么这样做是这样的,但实例方法代理的基本类方法已经以某种形式存在,因为动作管理器的早期阶段