Project

General

Profile

Actions

Feature #22486

open

Anonymous method

Feature #22486: Anonymous method

Added by UlyssesZhan (Ulysses Zhan) about 1 hour ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:127274]

Description

I propose an API Method.new(receiver, name = nil, &block) to define an anonymous singleton method and UnboundMethod.new(owner, name = nil, &block) to define an anonymous instance method. The default value of name can be :anonymous for compatibility concern (existing code bases may have been assuming Method#name is not nil). This functionality can currently be achieved in pure Ruby as follows:

def Method.new receiver, name = :anonymous, &body
	old = begin
		receiver.singleton_method name
	rescue NameError
		nil
	end
	receiver.define_singleton_method name, &body
	result = receiver.method name
	if old
		receiver.define_singleton_method name, old
	else
		receiver.singleton_class.undef_method name
	end
	result
end

def UnboundMethod.new owner, name = :anonymous, &body
	old = begin
		owner.instance_method name
	rescue NameError
		nil
	end
	owner.define_method name, &body
	result = owner.instance_method name
	if old
		owner.define_method name, old
	else
		owner.undef_method name
	end
	result
end

A use case is when one wants to pass a block with a block argument to instance_exec. For example:

module DefExtend
	def def_extend name, &body
		define_method name do |first_arg, *args, **opts, &block|
			puts "called with #{first_arg}"
			Method.new(self, &body).(*args, **opts, &block)
		end
	end
end

class C
	extend DefExtend
	def_extend(:foo) { |&block| block.(2) }
end

p C.new.foo(1) { _1 * 2 }

No data to display

Actions

Also available in: PDF Atom