簡體   English   中英

Ruby類與實例方法的混淆

[英]Ruby class vs instance method confusion

鑒於課程:

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

以及以下測試代碼:

c = Contact.new
UserMailer.contact_email(c)

這段代碼是如何工作的? 我認為我的contact_email是一個實例方法,但它作為一個類方法被調用,並且它可以工作。

感謝您的幫助 - 我學習Ruby和Rails :)

-標記

乍一看,這看起來是錯誤的,這是完全正確的。

它的工作原理是因為類上有一個method_missing參見source ),看起來像這樣

  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

action_methods基本上是郵件程序的名稱,對應於可以發送的電子郵件,而MessageDelivery是一個小代理類,最終會做

YourMailer.new.send(:contact_mailer, ...)

在我的腦海中,我不完全確定為什么這樣做是這樣的,但實例方法代理的基本類方法已經以某種形式存在,因為動作管理器的早期階段

檢查來源

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

示例實施:

class MyMailer
  def self.method_missing(method, *args)
    puts "Here, I can call any instance method" 
  end

  def sending_mail_for_you 
    puts "I am actually sending mail for you"
  end  

end
#notice, fake_method is not defined in the MyMailer class.
MyMailer.fake_method
This will give output: 
=> "Here, I can call any instance method"
"I am actually sending mail for you"

ActionMailer :: Base執行類似上面代碼的操作。 即使我們在執行method_missing部分時仍然沒有任何名為"fake_method"方法,它在內部調用你的'sending_mail_for_you'方法。

暫無
暫無

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

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