William James
9/3/2007 10:55:00 PM
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