aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support
diff options
context:
space:
mode:
authorJon Leighton <j@jonathanleighton.com>2012-04-12 09:02:39 -0700
committerJon Leighton <j@jonathanleighton.com>2012-04-12 09:02:39 -0700
commit018e832d844f8ca480f5af2e6ec78a2ca284e9c6 (patch)
tree6cc8891f8763dc88c870b9189f30d3bd0e0b23b3 /activesupport/lib/active_support
parent65be11ffecdf58e6b69fa84ea3547cd3201d2329 (diff)
parent300868d9cbf52bf268ba81ec289a257f8dc186ae (diff)
downloadrails-018e832d844f8ca480f5af2e6ec78a2ca284e9c6.tar.gz
rails-018e832d844f8ca480f5af2e6ec78a2ca284e9c6.tar.bz2
rails-018e832d844f8ca480f5af2e6ec78a2ca284e9c6.zip
Merge pull request #2733 from dasch/improve-delegate
Improve the performance of #delegate
Diffstat (limited to 'activesupport/lib/active_support')
-rw-r--r--activesupport/lib/active_support/core_ext/module/delegation.rb24
1 files changed, 14 insertions, 10 deletions
diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb
index af92b869fd..ee8adae1cb 100644
--- a/activesupport/lib/active_support/core_ext/module/delegation.rb
+++ b/activesupport/lib/active_support/core_ext/module/delegation.rb
@@ -1,5 +1,5 @@
class Module
- # Provides a delegate class method to easily expose contained objects' methods
+ # Provides a delegate class method to easily expose contained objects' public methods
# as your own. Pass one or more methods (specified as symbols or strings)
# and the name of the target object via the <tt>:to</tt> option (also a symbol
# or string). At least one method and the <tt>:to</tt> option are required.
@@ -124,23 +124,27 @@ class Module
file, line = caller.first.split(':', 2)
line = line.to_i
- if allow_nil
- methods.each do |method|
+ methods.each do |method|
+ method = method.to_s
+
+ # Attribute writer methods only accept one argument. Makes sure []=
+ # methods still accept two arguments.
+ definition = (method =~ /[^\]]=$/) ? "arg" : "*args, &block"
+
+ if allow_nil
module_eval(<<-EOS, file, line - 2)
- def #{method_prefix}#{method}(*args, &block) # def customer_name(*args, &block)
+ def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block)
if #{to} || #{to}.respond_to?(:#{method}) # if client || client.respond_to?(:name)
- #{to}.__send__(:#{method}, *args, &block) # client.__send__(:name, *args, &block)
+ #{to}.#{method}(#{definition}) # client.name(*args, &block)
end # end
end # end
EOS
- end
- else
- methods.each do |method|
+ else
exception = %(raise "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
module_eval(<<-EOS, file, line - 1)
- def #{method_prefix}#{method}(*args, &block) # def customer_name(*args, &block)
- #{to}.__send__(:#{method}, *args, &block) # client.__send__(:name, *args, &block)
+ def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block)
+ #{to}.#{method}(#{definition}) # client.name(*args, &block)
rescue NoMethodError # rescue NoMethodError
if #{to}.nil? # if client.nil?
#{exception} # # add helpful message to the exception