Reputation: 83299
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 references add_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.
Upvotes: 0
Views: 117
Reputation: 32355
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:
Upvotes: 4