Skip to content

Commit

Permalink
Merge pull request #16964 from Agis-/issue-16956
Browse files Browse the repository at this point in the history
Make delegation work with the reserved words passed to `:to`
  • Loading branch information
matthewd committed Sep 19, 2014
2 parents c2dfc31 + 1a787eb commit 8b39dfd
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 1 deletion.
6 changes: 6 additions & 0 deletions activesupport/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
10 changes: 9 additions & 1 deletion activesupport/lib/active_support/core_ext/module/delegation.rb
Original file line number Diff line number Diff line change
@@ -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.
#
Expand Down Expand Up @@ -163,7 +171,7 @@ def delegate(*methods)
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 []=
Expand Down
11 changes: 11 additions & 0 deletions activesupport/test/core_ext/module_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,14 @@ def self.table_name
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
Expand Down Expand Up @@ -495,4 +501,9 @@ def duck; 'duck' end
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

0 comments on commit 8b39dfd

Please sign in to comment.