From: Robert Klemme Date: 2007-09-04T14:30:04+09:00 Subject: Re: with On 03.09.2007 23:50, 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. > > temp=["abc","thing"]. > map{|x| x.length}. > map{|x| x>5 ? 5 : x}. > inject(0){|sum,x|sum+x}. > to_f > if temp<0.0 > temp = 0.0 > end > a=temp**0.5 > > I like the 'with' version better. > >> Anyway, I do wonder whether all this can be nicely solved by using local >> variables. Basically #with does nothing else than binding a value to a >> local variable with limited scope. > > Ruby tries to avoid local variables wherever it can by chaining iterators together like in file-open-each-line-gsub. I tried to allow a block to be used for non-enumerable types as well. > > What .with does is producing a little space for writing a block instead of requiring to reorder the whole function just for adding this little piggy-bag change. > > Does it make sense now? Yes, thank you for the explanation! I know now what you were after. I am not sure I'd subscribe to the Ruby "tries to avoid local variables". Kind regards robert