Bug #11916 ยป fix-def-delegator.patch
lib/forwardable.rb | ||
---|---|---|
# q.push 23 #=> NoMethodError
|
||
#
|
||
def def_instance_delegator(accessor, method, ali = method)
|
||
receiver =
|
||
if method_defined?(accessor) || private_method_defined?(accessor)
|
||
"__send__(:#{accessor})"
|
||
else
|
||
accessor
|
||
end
|
||
line_no = __LINE__; str = %{
|
||
def #{ali}(*args, &block)
|
||
begin
|
||
#{accessor}.__send__(:#{method}, *args, &block)
|
||
#{receiver}.__send__(:#{method}, *args, &block)
|
||
rescue ::Exception
|
||
$@.delete_if{|s| ::Forwardable::FILE_REGEXP =~ s} unless ::Forwardable::debug
|
||
::Kernel::raise
|
||
end
|
||
end
|
||
}
|
||
# If it's not a class or module, it's an instance
|
||
begin
|
||
module_eval(str, __FILE__, line_no)
|
||
rescue
|
||
instance_eval(str, __FILE__, line_no)
|
||
end
|
||
end
|
||
alias delegate instance_delegate
|
test/test_forwardable.rb | ||
---|---|---|
end
|
||
end
|
||
def test_def_instance_delegator_using_args_method_as_receiver
|
||
%i[def_delegator def_instance_delegator].each do |m|
|
||
cls = forwardable_class(
|
||
receiver_name: :args,
|
||
type: :method,
|
||
visibility: :private
|
||
) do
|
||
__send__ m, :args, :delegated1
|
||
end
|
||
assert_same RETURNED1, cls.new.delegated1
|
||
end
|
||
end
|
||
def test_def_instance_delegator_using_block_method_as_receiver
|
||
%i[def_delegator def_instance_delegator].each do |m|
|
||
cls = forwardable_class(
|
||
receiver_name: :block,
|
||
type: :method,
|
||
visibility: :private
|
||
) do
|
||
__send__ m, :block, :delegated1
|
||
end
|
||
assert_same RETURNED1, cls.new.delegated1
|
||
end
|
||
end
|
||
def test_def_instance_delegators
|
||
%i[def_delegators def_instance_delegators].each do |m|
|
||
cls = forwardable_class do
|
||
... | ... | |
end
|
||
end
|
||
def test_def_instance_delegators_using_args_method_as_receiver
|
||
%i[def_delegators def_instance_delegators].each do |m|
|
||
cls = forwardable_class(
|
||
receiver_name: :args,
|
||
type: :method,
|
||
visibility: :private
|
||
) do
|
||
__send__ m, :args, :delegated1, :delegated2
|
||
end
|
||
assert_same RETURNED1, cls.new.delegated1
|
||
assert_same RETURNED2, cls.new.delegated2
|
||
end
|
||
end
|
||
def test_def_instance_delegators_using_block_method_as_receiver
|
||
%i[def_delegators def_instance_delegators].each do |m|
|
||
cls = forwardable_class(
|
||
receiver_name: :block,
|
||
type: :method,
|
||
visibility: :private
|
||
) do
|
||
__send__ m, :block, :delegated1, :delegated2
|
||
end
|
||
assert_same RETURNED1, cls.new.delegated1
|
||
assert_same RETURNED2, cls.new.delegated2
|
||
end
|
||
end
|
||
def test_instance_delegate
|
||
%i[delegate instance_delegate].each do |m|
|
||
cls = forwardable_class do
|
||
... | ... | |
end
|
||
end
|
||
def test_def_instance_delegate_using_args_method_as_receiver
|
||
%i[delegate instance_delegate].each do |m|
|
||
cls = forwardable_class(
|
||
receiver_name: :args,
|
||
type: :method,
|
||
visibility: :private
|
||
) do
|
||
__send__ m, delegated1: :args, delegated2: :args
|
||
end
|
||
assert_same RETURNED1, cls.new.delegated1
|
||
assert_same RETURNED2, cls.new.delegated2
|
||
end
|
||
end
|
||
def test_def_instance_delegate_using_block_method_as_receiver
|
||
%i[delegate instance_delegate].each do |m|
|
||
cls = forwardable_class(
|
||
receiver_name: :block,
|
||
type: :method,
|
||
visibility: :private
|
||
) do
|
||
__send__ m, delegated1: :block, delegated2: :block
|
||
end
|
||
assert_same RETURNED1, cls.new.delegated1
|
||
assert_same RETURNED2, cls.new.delegated2
|
||
end
|
||
end
|
||
def test_def_single_delegator
|
||
%i[def_delegator def_single_delegator].each do |m|
|
||
cls = single_forwardable_class do
|
||
... | ... | |
private
|
||
def forwardable_class(&block)
|
||
def forwardable_class(
|
||
receiver_name: :receiver,
|
||
type: :ivar,
|
||
visibility: :public,
|
||
&block
|
||
)
|
||
Class.new do
|
||
extend Forwardable
|
||
def initialize
|
||
@receiver = RECEIVER
|
||
define_method(:initialize) do
|
||
instance_variable_set("@#{receiver_name}", RECEIVER)
|
||
end
|
||
if type == :method
|
||
attr_reader(receiver_name)
|
||
__send__(visibility, receiver_name)
|
||
end
|
||
class_exec(&block)
|