From: William James Date: 2007-09-04T07:55:06+09:00 Subject: Re: with Matthias W�chter wrote: > Robert Klemme schrieb: > > Somewhere above you completely lost me - it is especially unclear to me > > what "a_very_long_calculation" is supposed to be. Is this a variable > > name? Is this a placeholder for a long expression? > > It's the latter. > > Suppose you do a calculation like the following: > > a=["abc","thing"]. > map{|x| x.length}. > inject(0){|sum,x|sum+x}. > to_f**0.5 > > (this is only for the sake of example, don't try to make sense out of it). > > When I want to insert a function between .map and .inject, I can simply do that: > > a=["abc","thing"]. > map{|x| x.length}. > map{|x| x>5 ? 5 : x}. > inject(0){|sum,x|sum+x}. > to_f**0.5 > > I don't have to change any part of the expression before or after my change, it's just an *insert*. > > But I can't do the same for values that are not arrays. Say, after .to_f I want to set bounds on the value so that the square root function does not raise an exception. Then .with is useful. > > a=["abc","thing"]. > map{|x| x.length}. > map{|x| x>5 ? 5 : x}. > inject(0){|sum,x|sum+x}. > to_f. > with{|f| f<0.0 ? 0.0 : f}**0.5 > > Otherwise I'd have to split execution at this place, assign to a temporary variable, make my calculation and continue the expression later on. So "with" lets you keep the chain going. This won't do that, but it avoids a temporary variable: a = [ ["abc","thing"]. map{|x| x.size }. map{|x| x>5 ? 5 : x}. inject{|sum,x| sum + x }. to_f, 0.0 ].max ** 0.5 As suggested by someone else, "instance_eval" can be used: a = ["abc","thing"]. map{|x| x.size }. map{|x| x>5 ? 5 : x}. inject{|sum,x| sum + x }. to_f.instance_eval{ [self, 0.0].max} ** 0.5