Allow DelegateClass() to module_eval given block

Methods that return classes often module_eval the given block
(e.g. Class.new and Struct.new).  This allows DelegateClass to
work similarly.  This makes it easier to use DelegateClass
directly without subclassing, so as not to create an unnecessary
subclass.

Implements [Feature #15842]
This commit is contained in:
Jeremy Evans 2019-05-11 16:32:00 -07:00
parent 856593cc49
commit 1cd93f1cdf
3 changed files with 22 additions and 1 deletions

5
NEWS
View File

@ -118,6 +118,11 @@ Date::
new Japanese era as an informal extension, until the new JIS X 0301 is new Japanese era as an informal extension, until the new JIS X 0301 is
issued. [Feature #15742] issued. [Feature #15742]
Delegate::
* Object#DelegateClass accepts a block and module_evals it in the context
of the returned class, similar to Class.new and Struct.new.
ERB:: ERB::
* Prohibit marshaling ERB instance. * Prohibit marshaling ERB instance.

View File

@ -360,6 +360,14 @@ end
# end # end
# end # end
# #
# or:
#
# MyClass = DelegateClass(ClassToDelegateTo) do # Step 1
# def initialize
# super(obj_of_ClassToDelegateTo) # Step 2
# end
# end
#
# Here's a sample of use from Tempfile which is really a File object with a # Here's a sample of use from Tempfile which is really a File object with a
# few special rules about storage location and when the File should be # few special rules about storage location and when the File should be
# deleted. That makes for an almost textbook perfect example of how to use # deleted. That makes for an almost textbook perfect example of how to use
@ -383,7 +391,7 @@ end
# # ... # # ...
# end # end
# #
def DelegateClass(superclass) def DelegateClass(superclass, &block)
klass = Class.new(Delegator) klass = Class.new(Delegator)
methods = superclass.instance_methods methods = superclass.instance_methods
methods -= ::Delegator.public_api methods -= ::Delegator.public_api
@ -410,5 +418,6 @@ def DelegateClass(superclass)
klass.define_singleton_method :protected_instance_methods do |all=true| klass.define_singleton_method :protected_instance_methods do |all=true|
super(all) | superclass.protected_instance_methods super(all) | superclass.protected_instance_methods
end end
klass.module_eval(&block) if block
return klass return klass
end end

View File

@ -22,6 +22,13 @@ class TestDelegateClass < Test::Unit::TestCase
assert_equal(:m, obj.m, "[ruby-dev:33116]") assert_equal(:m, obj.m, "[ruby-dev:33116]")
end end
def test_delegate_class_block
klass = DelegateClass(Array) do
alias foo first
end
assert_equal(1, klass.new([1]).foo)
end
def test_systemcallerror_eq def test_systemcallerror_eq
e = SystemCallError.new(0) e = SystemCallError.new(0)
assert((SimpleDelegator.new(e) == e) == (e == SimpleDelegator.new(e)), "[ruby-dev:34808]") assert((SimpleDelegator.new(e) == e) == (e == SimpleDelegator.new(e)), "[ruby-dev:34808]")