开发者

about ruby class method invoke

in rails3 i defined a class

#coding:utf-8
clas开发者_开发百科s CoreMail < ActionMailer::Base
  def consulting_reply(email)
    mail(:to => email, :subject => 'ssss')

  end



end

i found i could invoke this method like this

CoreMail.consulting_reply(email)

but want i thought the right way is :

instance=CoreMail.new
instance.consulting_reply(email)

because the consulting_reply is the instance method,

did i missing something? hope someone could give me a help


ActionMailer::Base has a method_missing defined on it:

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

This will call your instance method with the same arguments and then call the message method, returning the object of that mailer call. To deliver it, call deliver! on the end of your method call:

CoreMail.consulting_reply(email).deliver!


You're right, normally that would be an instance method and you would have to create an instance of the class before calling consulting_reply() (since it's not defined as self.consulting_reply). However, your class is inheriting from ActionMailer::Base, and there's a little ruby magic happening behind the scenes. Checkout the source for ActionMailer::Base to see it for yourself (https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/base.rb), but to simplify for you what's happening, here's a quick example:

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

Test.fake_class_method

Which will output:

Called by a non class method

ActionMailer::Base does something similar to this, which dynamically looks for the method you called. I believe it also creates a instance of the class using:

new(method, *args).message

Anyway, I hope this sheds some light as to what's happening.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜