Simple object loops and what they return

Hi --

> 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 { ... } -> 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 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.

I'm thinking it might be because people may not know that break
can take a value and it is returned by the loop expression
(even the method loops). I actually haven't found this useful
(and quite natural after thinking about it) behavior
documented.

(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.)

You're right in that will never return the loop exited normally
case (with nil) becasue it is infinite, but if you use you can
get it to return something:

loop{x=rand(20);break(true) if x==7;break(nil) if x==13}

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.

Even these non-traditional loops (and even if/else and case)
could have been implemented as Kernel methods. If they were,
you'd have syntax like this:

while(proc{<cond>}) {<body>}
if(proc{<cond>},proc{<if-body>}) {<else-body>}

And in ruby 1.9, the proc keyword isn't needed - sweet. If
ruby is pretty efficient at making/using procs, this might be a
good idea to make the language even cleaner (the current
while/etc would just be a shorthand). Here is an
implementation:

def while_method(condition=nil,&body)
    if not body
        while(condition); end
    elsif not condition
        while(body); end
    else
        while(condition); body; end
    end
end

# same as x=0;while x<10; puts(x);x+=1; end
x=0;while_method(proc{x<10}) {puts(x);x+=1}

# same as x=0;begin puts(x);x+=1 end while x<10
x=0;while_method {puts(x);x+=1;x<10}

Yahoo! Mail
Stay connected, organized, and protected. Take the tour:
http://tour.mail.yahoo.com/mailtour.html

ยทยทยท

--- "David A. Black" <dblack@wobblini.net> wrote:

On Thu, 12 May 2005, Eric Mahurin wrote: