Feature #6717
closed
Method like #instance_eval that returns self (like #tap)
Added by alexeymuranov (Alexey Muranov) almost 12 years ago.
Updated almost 12 years ago.
Description
=begin
How about adding a method that acts like (({#instance_eval})), but returns (({self}))?
Call it (({Object#instance_tap})) for example, or (({Object#tweak!})):
class Object
def tweak!(*args, &block)
instance_eval(*args, &block); self
end
end
This can be used to initialize a hash. Instead of:
room_numbers = (1..10).each_with_object({}) { |n, o| o[n] = 100 + n }
one would write:
room_numbers = {}.tweak! { (1..10).each { |n| self[n] = 100 +n } }
Googling for this kind of method gave me this:
http://yuroyoro-blog.tumblr.com/post/24113917395/ruby-tap-instance-eval-tapeval
=end
=begin
For a few hours already i like this method so much, that i want to propose a short name for it: (({Object#!})) :) :
room_numbers = {}.! { (1..10).each { |n| self[n] = 100 + n } }
=end
=begin
I'm against adding new methods which call (({instance_eval})) under the hood.
=end
=begin
It seems to me that the main question is if to allow new methods that act like (({instance_eval})), or call it under the hood. The advantage in my opinion is the possibility to use (({self})), instead of choosing and declaring a local variable like in:
room_numbers = {}.tap { |h| (1..10).each { |n| h[n] = 100 + n } }
and that the object itself can be modified. ((({tap})) will modify in place.)
=end
on the other hand that approach won't be suitable for nested tweak calls :)
=begin
Another idea: how about "associating" this method with "public self" requested in #6373?
class Object
def self
self
end
def self!(&block)
instance_eval(&block)
self
end
end
room_numbers = {}.self! { (1..10).each { |n| store(n, 100 + n) } }
Other possible names: (({Object#_})) and (({Object#!}))
=end
=begin
I think i've understood the concern of ((nobu)): object's private methods will be accessible from the block. This is not what i wanted. Sorry, i'll need to think more about my proposal. Maybe it is not good and (({tap})) is enough.
Here is why i am thinking about this: i want to be able to alter an object by calling methods on it, instead of passing the object as an argument (like in (({each_with_object}))).
=end
=begin
If nobody has anything interesting to say about this, the issue can be closed, as i think (({tap})) works fine here, even in:
hash = {}.tap { |h| h.tap { |hh| hh[1] = 2 } } # => {1=>2}
"Tap" just sounded strange to me in this use case. I wanted something like (({instance_eval})) that (1) returns self and (2) can only call public methods.
((rosenfeld)), what did you mean by "won't be suitable for nested tweak calls"?
=end
- Status changed from Open to Rejected
alexeymuranov (Alexey Muranov) wrote:
((rosenfeld)), what did you mean by "won't be suitable for nested tweak calls"?
=begin
{}.self! { {}.self! { store(...) } }
=end
Which store is used?
Also available in: Atom
PDF
Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0