Skip to content

Commit a21fe2a

Browse files
hsbtbyroot
andcommitted
[ruby/delegate] Reapply "Merge pull request #46 from byroot/use-forward-send"
This reverts commit ruby/delegate@fc2bd0498af0. ruby/delegate@7d5c1e0842 Co-authored-by: Jean Boussier <[email protected]>
1 parent bdf99bf commit a21fe2a

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

lib/delegate.rb

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,17 @@ def DelegateClass(superclass, &block)
405405
protected_instance_methods -= ignores
406406
public_instance_methods = superclass.public_instance_methods
407407
public_instance_methods -= ignores
408+
409+
normal, special = public_instance_methods.partition { |m| m.match?(/\A[a-zA-Z]\w*[!\?]?\z/) }
410+
411+
source = normal.map do |method|
412+
"def #{method}(...); __getobj__.#{method}(...); end"
413+
end
414+
415+
protected_instance_methods.each do |method|
416+
source << "def #{method}(...); __getobj__.__send__(#{method.inspect}, ...); end"
417+
end
418+
408419
klass.module_eval do
409420
def __getobj__ # :nodoc:
410421
unless defined?(@delegate_dc_obj)
@@ -413,18 +424,21 @@ def __getobj__ # :nodoc:
413424
end
414425
@delegate_dc_obj
415426
end
427+
416428
def __setobj__(obj) # :nodoc:
417429
__raise__ ::ArgumentError, "cannot delegate to self" if self.equal?(obj)
418430
@delegate_dc_obj = obj
419431
end
420-
protected_instance_methods.each do |method|
421-
define_method(method, Delegator.delegating_block(method))
422-
protected method
423-
end
424-
public_instance_methods.each do |method|
432+
433+
class_eval(source.join(";"), __FILE__, __LINE__)
434+
435+
special.each do |method|
425436
define_method(method, Delegator.delegating_block(method))
426437
end
438+
439+
protected(*protected_instance_methods)
427440
end
441+
428442
klass.define_singleton_method :public_instance_methods do |all=true|
429443
super(all) | superclass.public_instance_methods
430444
end

test/test_delegate.rb

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,21 @@ def test_override
9393
end
9494

9595
class Parent
96-
def parent_public; end
96+
def parent_public
97+
:public
98+
end
9799

98100
protected
99101

100-
def parent_protected; end
102+
def parent_protected
103+
:protected
104+
end
101105

102106
private
103107

104-
def parent_private; end
108+
def parent_private
109+
:private
110+
end
105111
end
106112

107113
class Child < DelegateClass(Parent)
@@ -157,6 +163,13 @@ def test_DelegateClass_public_instance_method
157163
assert_instance_of UnboundMethod, Child.public_instance_method(:to_s)
158164
end
159165

166+
def test_call_visibiltiy
167+
obj = Child.new(Parent.new)
168+
assert_equal :public, obj.parent_public
169+
assert_equal :protected, obj.__send__(:parent_protected)
170+
assert_raise(NoMethodError) { obj.__send__(:parent_private) }
171+
end
172+
160173
class IV < DelegateClass(Integer)
161174
attr_accessor :var
162175

0 commit comments

Comments
 (0)