aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
authorAgis- <corestudiosinc@gmail.com>2014-09-18 23:55:13 +0300
committerAgis- <corestudiosinc@gmail.com>2014-09-19 11:41:41 +0300
commit1a787ebb7e4366147bf83ed7bb8b362164c841d5 (patch)
treed0d1b00858243346d4fd5bb249da2d0c59cf8e5b /activesupport
parentc2dfc316912e780dfd6113e6ab9668128264f111 (diff)
downloadrails-1a787ebb7e4366147bf83ed7bb8b362164c841d5.tar.gz
rails-1a787ebb7e4366147bf83ed7bb8b362164c841d5.tar.bz2
rails-1a787ebb7e4366147bf83ed7bb8b362164c841d5.zip
Delegation works with reserved words passed to `:to`
Fixes #16956.
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG.md6
-rw-r--r--activesupport/lib/active_support/core_ext/module/delegation.rb10
-rw-r--r--activesupport/test/core_ext/module_test.rb11
3 files changed, 26 insertions, 1 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 8f328335b2..4204057737 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,9 @@
+* Delegation now works with ruby reserved words passed to `:to` option.
+
+ Fixes #16956.
+
+ *Agis Anastasopoulos*
+
* Added method `#eql?` to `ActiveSupport::Duration`, in addition to `#==`.
Currently, the following returns `false`, contrary to expectation:
diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb
index e926392952..570585b89a 100644
--- a/activesupport/lib/active_support/core_ext/module/delegation.rb
+++ b/activesupport/lib/active_support/core_ext/module/delegation.rb
@@ -1,8 +1,16 @@
+require 'set'
+
class Module
# Error generated by +delegate+ when a method is called on +nil+ and +allow_nil+
# option is not used.
class DelegationError < NoMethodError; end
+ RUBY_RESERVED_WORDS = Set.new(
+ %w(alias and BEGIN begin break case class def defined? do else elsif END
+ end ensure false for if in module next nil not or redo rescue retry
+ return self super then true undef unless until when while yield)
+ ).freeze
+
# Provides a +delegate+ class method to easily expose contained objects'
# public methods as your own.
#
@@ -163,7 +171,7 @@ class Module
line = line.to_i
to = to.to_s
- to = 'self.class' if to == 'class'
+ to = "self.#{to}" if RUBY_RESERVED_WORDS.include?(to)
methods.each do |method|
# Attribute writer methods only accept one argument. Makes sure []=
diff --git a/activesupport/test/core_ext/module_test.rb b/activesupport/test/core_ext/module_test.rb
index 380f5ad42b..3c49c4d14f 100644
--- a/activesupport/test/core_ext/module_test.rb
+++ b/activesupport/test/core_ext/module_test.rb
@@ -56,8 +56,14 @@ Developer = Struct.new(:client) do
delegate :name, :to => :client, :prefix => nil
end
+Event = Struct.new(:case) do
+ delegate :foo, :to => :case
+end
+
Tester = Struct.new(:client) do
delegate :name, :to => :client, :prefix => false
+
+ def foo; 1; end
end
Product = Struct.new(:name) do
@@ -495,4 +501,9 @@ class MethodAliasingTest < ActiveSupport::TestCase
assert_equal 'duck_with_orange', @instance.duck
assert FooClassWithBarMethod.public_method_defined?(:duck)
end
+
+ def test_delegate_with_case
+ event = Event.new(Tester.new)
+ assert_equal 1, event.foo
+ end
end