From: Eric Mahurin Date: 2005-05-13T04:06:48+09:00 Subject: Re: simple object loops and what they return I made a little in-line perl script for attempting to find all of the stdlib ruby files that use the return value of one the object loops in question. I would have done Ruby except it can't do the equivalent of the regular expression construct (??{$RE}) for doing parenthesis/bracket/brace matching. Here are the results: perl -e '$method = qr(each|each_with_index|each_index|reverse_each|each_key|each_value|each_pair|each_byte|each_line|times|upto|downto|step|scan); $block=qr(\{(?:[^\{\}]|(??{$block}))*\});$/=undef;while(<>){while(/(.*\.\s*$method\s*$block[ \t]*(?!\#|\s|if|while|until).*|^.*\S+[ \t\=]+\S+.*\.\s*$method\s*(?:\{|do).*)/g){$m=$1;$m=~s/\s+/ /g;print("$ARGV:$m\n")};while(/(\.\s*$method\b|\b(while|until|loop|for(?=.*\bin\b))\b)\b/g){$m=$1;$m=~s/\s//g;$usage{$m}+=1}}for(sort(keys(%usage))){print("$_ => $usage{$_}\n")}' `find . -name '*.rb'` ./optparse.rb: RCSID = %w$Id: optparse.rb,v 1.40.2.4 2004/12/05 10:39:58 nobu Exp $[1..-1].each {|s| s.freeze}.freeze ./optparse.rb: parse(*IO.readlines(filename).each {|s| s.chomp!}) ./rexml/element.rb: prefix = attributes.prefixes.each { |prefix| return "#{prefix}:" if namespace( prefix ) == namespace } || '' # this each return value isn't used, but the dumb script above thinks so ./rexml/validation/relaxng.rb: @choices.each { |c| c.each { |s| s.reset if s.kind_of? State } } .downto => 5 .each => 1091 .each_byte => 19 .each_index => 10 .each_key => 5 .each_line => 4 .each_pair => 5 .each_value => 17 .each_with_index => 23 .reverse_each => 17 .scan => 79 .step => 14 .times => 32 .upto => 28 for => 272 loop => 61 until => 96 while => 375 Of all of the method loops above, it only looks like the return value of "each" is used. And then only 3 times (out of 1091). 0.3% doesn't sound that useful. I still haven't found an instance of any of the other method loops above where the return value is used. Would anybody support an RCR with all but each changed to return nil? Notice I added a few more method loops to the list. All of these method loops don't modify the receiver and return the receiver. --- Robert Klemme wrote: > David A. Black wrote: > > Hi -- > > > > On Thu, 12 May 2005, Eric Mahurin wrote: > > > >> inject clearly does what is supposed to. I'm not > referring to > >> it. I'm referring to the following loops that are similar > to > >> plain while/until/loop loops: > >> > >> enum.each {|o| ...} -> enum or break value > >> enum.each_with_index {|o,i| ...} -> enum or break value > >> for o in enum; ... end -> enum or break value > >> int.times {|i| ...} -> int or break value > >> int.downto(stop) {|i| ...} -> int or break value > >> int.upto(stop) {|i| ...} -> int or break value > >> int.step(stop,step) {|i| ...} -> int or break value > >> > >> Compare this to the traditional loops: > >> > >> loop { ... } -> nil or break value > >> while ...; ... end -> nil or break value > >> until ...; ... end -> nil or break value > >> begin ... end while ... -> nil or break value > >> begin ... end until ... -> nil or break value > >> > >> I guess many may not know that break can take a value as > an > >> argument and make the broken loop return that. I find > this > >> behavior quite useful except for those loops that return > >> something other than nil in the no-break case (the object > loops > >> above). > >> > >> What about the Integer loops above? Anybody using what > those > >> return now - the original int? Maybe I could propose just > >> those loops. > > I think they normally return the original int value, just > like each: > > >> 10.times {} > => 10 > >> 10.times { break "foo" } > => "foo" > > > I wonder whether some of the non-consensus about the > changes you've > > been discussing originates in the difference between loop > constructs > > per se, and iterators. (loop itself appears to be a > method, though > > oddly it does not identify itself as an iterator. But an > infinite > > loop can't really "return" anything anyway.) > > >> x = loop do; break "foo"; end > => "foo" > >> x > => "foo" > > Sorry, couldn't resist. :-)) > > > So the non-traditional loops you've listed are basically > method calls > > (including 'for', which I believe is just an 'each' > wrapper). I don't > > know that this has to be a determinant one way or the > other, but I > > realize it's something that I'd semi-perceived but not > quite put my > > finger on that separates these things into two pretty > distinct > > categories. > > Eventually there's most likely a loop construct buried - even > in those > method calls... The difference might be smaller than you > think: both are > expressions that return something, so the difference between > while and > each is not too big. > > Kind regards > > robert > > > __________________________________ Yahoo! Mail Mobile Take Yahoo! Mail with you! Check email on your mobile phone. http://mobile.yahoo.com/learn/mail