Ruby class vs 实例方法混淆
Ruby class vs instance method confusion
给定 class:
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 是一个实例方法,但它被作为 class 方法调用,并且它有效。
感谢您的帮助 - 在我学习 Ruby 和 Rails :)
-标记
乍一看这看起来不对,你完全正确。
之所以有效,是因为有一个 method_missing
class (see 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
是一个小代理 class 最终会做
YourMailer.new.send(:contact_mailer, ...)
我不明白为什么要这样做,但是实例方法代理的基本 class 方法从很早以前就以一种或另一种形式存在动作邮件
勾选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
实施示例:
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 做的事情类似于上面的代码。
即使我们没有任何这样的方法称为 "fake_method"
仍然在执行 method_missing 部分时,它会在内部调用您的 'sending_mail_for_you'
方法。
给定 class:
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 是一个实例方法,但它被作为 class 方法调用,并且它有效。
感谢您的帮助 - 在我学习 Ruby 和 Rails :)
-标记
乍一看这看起来不对,你完全正确。
之所以有效,是因为有一个 method_missing
class (see 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
是一个小代理 class 最终会做
YourMailer.new.send(:contact_mailer, ...)
我不明白为什么要这样做,但是实例方法代理的基本 class 方法从很早以前就以一种或另一种形式存在动作邮件
勾选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
实施示例:
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 做的事情类似于上面的代码。
即使我们没有任何这样的方法称为 "fake_method"
仍然在执行 method_missing 部分时,它会在内部调用您的 'sending_mail_for_you'
方法。