summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2025-12-17 12:56:19 +0900
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2025-12-18 16:46:29 +0900
commita21fe2adfe3b4e4496f89e35d5a5a8cf11bf1ca0 (patch)
treebf88cdd30672a6d81f3203057468e873cbf1299e /lib
parentbdf99bf0dc3adf15f653dd8c02fce9d6ba946af5 (diff)
[ruby/delegate] Reapply "Merge pull request #46 from byroot/use-forward-send"
This reverts commit https://github.com/ruby/delegate/commit/fc2bd0498af0. https://github.com/ruby/delegate/commit/7d5c1e0842 Co-authored-by: Jean Boussier <byroot@ruby-lang.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/delegate.rb24
1 files changed, 19 insertions, 5 deletions
diff --git a/lib/delegate.rb b/lib/delegate.rb
index 7c403b2747..5ba94da060 100644
--- a/lib/delegate.rb
+++ b/lib/delegate.rb
@@ -405,6 +405,17 @@ def DelegateClass(superclass, &block)
protected_instance_methods -= ignores
public_instance_methods = superclass.public_instance_methods
public_instance_methods -= ignores
+
+ normal, special = public_instance_methods.partition { |m| m.match?(/\A[a-zA-Z]\w*[!\?]?\z/) }
+
+ source = normal.map do |method|
+ "def #{method}(...); __getobj__.#{method}(...); end"
+ end
+
+ protected_instance_methods.each do |method|
+ source << "def #{method}(...); __getobj__.__send__(#{method.inspect}, ...); end"
+ end
+
klass.module_eval do
def __getobj__ # :nodoc:
unless defined?(@delegate_dc_obj)
@@ -413,18 +424,21 @@ def DelegateClass(superclass, &block)
end
@delegate_dc_obj
end
+
def __setobj__(obj) # :nodoc:
__raise__ ::ArgumentError, "cannot delegate to self" if self.equal?(obj)
@delegate_dc_obj = obj
end
- protected_instance_methods.each do |method|
- define_method(method, Delegator.delegating_block(method))
- protected method
- end
- public_instance_methods.each do |method|
+
+ class_eval(source.join(";"), __FILE__, __LINE__)
+
+ special.each do |method|
define_method(method, Delegator.delegating_block(method))
end
+
+ protected(*protected_instance_methods)
end
+
klass.define_singleton_method :public_instance_methods do |all=true|
super(all) | superclass.public_instance_methods
end