[英]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.