While reading the book Programming Ruby, one example shows how blocks can be used as closure:
def nTimes(aThing)
return proc {|n| aThing * n}
end
p = nTimes("Hello ")
Now if we output the value of p.call(3) , it would be Hello Hello Hello
However, if our code was simply puts 3 * "Hello " , Ruby would complain about incompatible type.
Why? Thanks.
Your problem has nothing to do with closures or blocks. It is related to how operators are handled in Ruby.
On binary operations like
*and+, the object to the left of the operand is the receiver of the method. So when you do"hello " * 3it calls the*method on the classStringand passes3as a parameter. The definition ofString#*takes integers as parameters and returnsselfrepeated that many times, hence the output"hello hello hello ".But if you phrase it as
3 * "hello ", the*method of theFixnumclass is called, and"hello "is passed as a parameter.Fixnum#*doesn’t know what to do withStringparameters so you get an error.