oMiKeY oMiKeY - 1 year ago 57
Ruby Question

When are piped inputs necessary in Ruby? (|x| x.to_s)

I have recently found out that the piped inputs that many ruby methods use are not necessary some of the time, but this seems to be inconsistent. For example, this line creates an array of strings for yesterday, today, and tomorrow:{[prev_day, to_datetime, tomorrow]}.map{|d| d.strftime('%m/%d/%Y')}
=> ["06/20/2016", "06/21/2016", "06/22/2016"]

As you can see within instance_eval, there is no piped input, and the function simply assumes that the methods are being called on But if I try to apply the same idea to the map method:{[prev_day, to_datetime, tomorrow]}.map{strftime('%m/%d/%Y')}
NoMethodError: undefined method `strftime' for main:Object

Suddenly it is trying to use the method on main?

My question is why did this work in the first method and not the second?

Answer Source

From the docs for instance_eval:

Evaluates a string containing Ruby source code, or the given block, within the context of the receiver (obj). In order to set the context, the variable self is set to obj while the code is executing, giving the code access to obj's instance variables and private methods.

instance_eval on the one hand is very special, because you call it on a instance and it was explicitly build to run the block in the context of instance. Therefore the method can always assume that the context of self is always the instance on which instance_eval was called.

map on the other hand is different: In your example you call it on an array, but the block should run on each object within the array, therefore you need to pass different objects to the block in each iteration.