Issue #10095 has been updated by Jihwan Song.


I realized that what is desired here is somewhat different than what can be achieved using class_eval, instance_eval and/or yield.

What is really desired is a way to define an unnamed instance method that has access only to public methods, that gets defined immediately and disappears(undefined) right after it was invoked once.

Let's say, we have this tiny functionality that probably never will be used again and need not be included in the definition of the class, but we wanna do it quickly by saying something like this:

john.yield(Time.now()) { |time| hungry? ? (time.is_morning? ? :eat_bagel : :eat_bread) : :sleep }

The context the block should be running in has to be within the instance, john. 'hungry?' is applied to john as if the block is defined as a instance method in the class.

However, this kind of usage of the instance should not break accessibility rule to make any exception. Although the block was programmed as if it was a def block in the class, it should not have any access to private methods.


----------------------------------------
Feature #10095: Object#as
https://bugs.ruby-lang.org/issues/10095#change-49014

* Author: Akira Matsuda
* Status: Open
* Priority: Normal
* Assignee: 
* Category: core
* Target version: current: 2.2.0
----------------------------------------
We've had so many times of feature requests for a method similar to Object#tap that doesn't return self but returns the given block's execution result (e.g. #7388, #6684, #6721 ).

I'm talking about something like this in Ruby of course:
Object.class_eval { def as() yield(self) end }

IIRC Matz is not against introducing this feature but he didn't like any of the names proposed in the past, such as embed, do, identity, ergo, reference, yield_self, itself, apply, map, tap!, etc.

So, let us propose a new name, Object#as today.
It's named from the aspect of the feature that it gives the receiver a new name "as" a block local variable.
For instance, the code reads so natural and intuitive like this:

(1 + 2 + 3 + 4).as {|x| x ** 2}
=> 100

Array.new.as {|a| a << 1; a << 2}
=> [1, 2]

---Files--------------------------------
itself-block.patch (1.35 KB)


-- 
https://bugs.ruby-lang.org/