I've seen a few places where开发者_如何学运维 *_without_*
methods are being referenced in gems, and I don't see where they're being defined. Here are two examples from the validationgroup
and delayed_jobs
gems.
In validation_group.rb, there is a method
add_with_validation_group
that is defined that referencesadd_without_validation_group
on its last line; however,add_without_validation_group
does not appear to be defined anywhere.def add_with_validation_group(attribute, msg = @@default_error_messages[:invalid], *args, &block) add_error = true if @base.validation_group_enabled? current_group = @base.current_validation_group found = ValidationGroup::Util.current_and_ancestors(@base.class). find do |klass| klasses = klass.validation_group_classes klasses[klass] && klasses[klass][current_group] && klasses[klass][current_group].include?(attribute) end add_error = false unless found end add_without_validation_group(attribute, msg, *args,&block) if add_error end
In DelayedJob's message_sending.rb, dynamically passed method parameters are being called as
#{method}_without_send_later
. However, I only see where#{method}_with_send_later
is being defined anywhere in this gem.def handle_asynchronously(method) without_name = "#{method}_without_send_later" define_method("#{method}_with_send_later") do |*args| send_later(without_name, *args) end alias_method_chain method, :send_later end
So my belief is that there's some Rails magic I'm missing with these "without" methods. However, I can't seem to figure out what to search for in Google to answer the question on my own.
that's what alias_method_chain
is providing you.
Basically when you say
alias_method_chain :some_method, :feature
You are provided two methods:
some_method_with_feature
some_method_without_feature
What happens is that when the original some_method
is called, it actually calls some_method_with_feature
. Then you get a reference to some_method_without_feature
which is your original method declaration (ie for fallback/default behavior). So, you'll want to define some_method_with_feature
to actually do stuff, which, as I say, is called when you call some_method
Example:
def do_something
"Do Something!!"
end
def do_something_with_upcase
do_something_without_upcase.upcase
end
alias_method_chain :do_something, :upcase
do_something # => "DO SOMETHING!!"
See the documentation here:
精彩评论