2010-12-17 70 views
0

在Rails3中我定义的类关于Ruby类方法调用

#coding:utf-8 
class CoreMail < ActionMailer::Base 
    def consulting_reply(email) 
    mail(:to => email, :subject => 'ssss') 

    end 



end 

,我发现我可以调用此方法像这样

CoreMail.consulting_reply(email) 

,但希望我认为正确的做法是:

instance=CoreMail.new 
instance.consulting_reply(email) 

因为consulting_reply是实例方法,因此

我错过了什么吗?希望有人能够给我一个帮助

回答

0

你说得对,通常这将是一个实例方法,你将不得不调用consulting_reply之前创建类的实例()(因为它没有被定义为self.consulting_reply)。然而,你的类继承自ActionMailer :: Base,并且在幕后发生了一些小红宝石魔法。查看ActionMailer :: Base的源代码以便自己查看(https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/base.rb),但为了简化您正在发生的事情,这里是一个简单的例子:

class Test 
    def self.method_missing(method, *args) 
    puts "Called by a non class method" 
    end 
end 

Test.fake_class_method 

将输出:

由非类方法调用

的ActionMailer :: Base的做一些与此类似,其动态查找您调用的方法。我相信它也创造了这个课程的一个实例:

new(method, *args).message 

无论如何,我希望这能说明发生了什么。

+0

这不是我发布的,只是更长?对不起,是一个糟糕的运动:( – 2010-12-17 06:47:11

+0

我写它的同时你写你的答案:P – joshaidan 2010-12-17 06:49:35

2

ActionMailer::Base有一个method_missing上定义:

def method_missing(method, *args) #:nodoc: 
    return super unless respond_to?(method) 
    new(method, *args).message 
end 

这将调用您的实例方法使用相同的参数,然后调用message方法,返回该邮件通话的对象。为了实现它,需要deliver!你的方法调用的末尾:

CoreMail.consulting_reply(email).deliver!