Return from a block?

Discussion in 'Ruby' started by Howard Lewis Ship, Jan 5, 2005.

  1. I've had a couple of places where I really needed to just return from
    a block. From what I can see, if my block is inside a method, the
    return will return from the method, not return control *to* the
    method. I've ended up writing some very Pascal like code:

    Find.find(*ARGV) do |f|

    if f =~ /[CVS|SVN]/
    Find.prune
    else
    $matches += 1 if match?(f)
    end
    end

    Where what I'd prefer to write would be:

    Find.find(*ARGV) do |f|

    if f =~ /[CVS|SVN]/
    Find.prune
    return-from-block-to-method
    end

    $matches += 1 if match?(f)
    end


    Is there a way to return control from the block to the method?

    --
    Howard M. Lewis Ship
    Independent J2EE / Open-Source Java Consultant
    Creator, Jakarta Tapestry
    Creator, Jakarta HiveMind

    Professional Tapestry training, mentoring, support
    and project work. http://howardlewisship.com
    Howard Lewis Ship, Jan 5, 2005
    #1
    1. Advertising

  2. Howard Lewis Ship

    Carlos Guest

    [Howard Lewis Ship <>, 2005-01-06 00.11 CET]
    > Is there a way to return control from the block to the method?


    next

    Good luck.
    Carlos, Jan 5, 2005
    #2
    1. Advertising

  3. Howard Lewis Ship

    Jamis Buck Guest

    On 08:17 Thu 06 Jan , Carlos wrote:
    > [Howard Lewis Ship <>, 2005-01-06 00.11 CET]
    > > Is there a way to return control from the block to the method?

    >
    > next
    >
    > Good luck.


    To elaborate a little more:

    a = proc { |i| next i+1 }
    p a.call(5)

    Hope that helps. I can understand why 'return' behaves like it does,
    but there are times I wish there was a more intuitive keyword for
    returning a value from a block. 'next' just feels wrong to me. :(

    - Jamis

    --
    Jamis Buck

    http://www.jamisbuck.org/jamis
    ------------------------------
    "I am Victor of Borge. You will be assimil-nine-ed."
    Jamis Buck, Jan 5, 2005
    #3
  4. Thanks ... there it is, plain as day, on page 345 of PickAxe 2nd edition.


    On Thu, 6 Jan 2005 08:35:14 +0900, Jamis Buck <> wrote:
    > On 08:17 Thu 06 Jan , Carlos wrote:
    > > [Howard Lewis Ship <>, 2005-01-06 00.11 CET]
    > > > Is there a way to return control from the block to the method?

    > >
    > > next
    > >
    > > Good luck.

    >
    > To elaborate a little more:
    >
    > a = proc { |i| next i+1 }
    > p a.call(5)
    >
    > Hope that helps. I can understand why 'return' behaves like it does,
    > but there are times I wish there was a more intuitive keyword for
    > returning a value from a block. 'next' just feels wrong to me. :(
    >
    > - Jamis
    >
    > --
    > Jamis Buck
    >
    > http://www.jamisbuck.org/jamis
    > ------------------------------
    > "I am Victor of Borge. You will be assimil-nine-ed."
    >
    >



    --
    Howard M. Lewis Ship
    Independent J2EE / Open-Source Java Consultant
    Creator, Jakarta Tapestry
    Creator, Jakarta HiveMind

    Professional Tapestry training, mentoring, support
    and project work. http://howardlewisship.com
    Howard Lewis Ship, Jan 5, 2005
    #4
  5. Hi,

    Am Donnerstag, 06. Jan 2005, 08:59:06 +0900 schrieb Howard Lewis Ship:
    > On Thu, 6 Jan 2005 08:35:14 +0900, Jamis Buck <> wrote:
    > >
    > > a = proc { |i| next i+1 }
    > > p a.call(5)
    > >

    > Thanks ... there it is, plain as day, on page 345 of PickAxe 2nd edition.


    Sorry, where are the page numbers in the online version?

    Bertram

    --
    Bertram Scharpf
    Stuttgart, Deutschland/Germany
    http://www.bertram-scharpf.de
    Bertram Scharpf, Jan 6, 2005
    #5
  6. Howard Lewis Ship

    Dave Thomas Guest

    On Jan 6, 2005, at 3:17 AM, Bertram Scharpf wrote:

    >> Thanks ... there it is, plain as day, on page 345 of PickAxe 2nd
    >> edition.

    >
    > Sorry, where are the page numbers in the online version?
    >

    If you're looking at it online, it's probably the first edition.

    Cheers


    Dave
    Dave Thomas, Jan 6, 2005
    #6
  7. "Carlos" <> schrieb im Newsbeitrag
    news:...
    > [Howard Lewis Ship <>, 2005-01-06 00.11 CET]
    >> Is there a way to return control from the block to the method?

    >
    > next


    "break "could work, too.

    Kind regards

    robert
    Robert Klemme, Jan 6, 2005
    #7
  8. Am Donnerstag, 06. Jan 2005, 18:32:52 +0900 schrieb Dave Thomas:
    >
    > On Jan 6, 2005, at 3:17 AM, Bertram Scharpf wrote:
    >
    > >>Thanks ... there it is, plain as day, on page 345 of PickAxe 2nd
    > >>edition.

    > >
    > >Sorry, where are the page numbers in the online version?
    > >

    > If you're looking at it online, it's probably the first edition.


    What a surprise.

    Anyway, I would have liked to know, what 'next <exp>' means.
    Never mind; in the meantime I found out.

    Bertram

    --
    Bertram Scharpf
    Stuttgart, Deutschland/Germany
    http://www.bertram-scharpf.de
    Bertram Scharpf, Jan 6, 2005
    #8
  9. Howard Lewis Ship

    E S Guest

    Jamis Buck wrote:
    > On 08:17 Thu 06 Jan , Carlos wrote:
    >
    >>[Howard Lewis Ship <>, 2005-01-06 00.11 CET]
    >>
    >>>Is there a way to return control from the block to the method?

    >>
    >>next
    >>
    >>Good luck.

    >
    >
    > To elaborate a little more:
    >
    > a = proc { |i| next i+1 }
    > p a.call(5)
    >
    > Hope that helps. I can understand why 'return' behaves like it does,
    > but there are times I wish there was a more intuitive keyword for
    > returning a value from a block. 'next' just feels wrong to me. :(


    For just returning control, throw...catch should work, for returning
    a value, Kernel.callcc? But Mr. Buck's solution is certainly shorter.

    E
    E S, Jan 6, 2005
    #9
  10. E S wrote:
    > Jamis Buck wrote:
    >
    >> On 08:17 Thu 06 Jan , Carlos wrote:
    >>
    >>> [Howard Lewis Ship <>, 2005-01-06 00.11 CET]
    >>>
    >>>> Is there a way to return control from the block to the method?
    >>>
    >>>
    >>> next
    >>>
    >>> Good luck.

    >>
    >>
    >>
    >> To elaborate a little more:
    >>
    >> a = proc { |i| next i+1 }
    >> p a.call(5)
    >>
    >> Hope that helps. I can understand why 'return' behaves like it does,
    >> but there are times I wish there was a more intuitive keyword for
    >> returning a value from a block. 'next' just feels wrong to me. :(

    >
    >
    > For just returning control, throw...catch should work, for returning
    > a value, Kernel.callcc? But Mr. Buck's solution is certainly shorter.


    throw...catch can be used for returning a value as well, by the way. A
    second parameter to "throw" is used as a return value from "catch".

    Gennady.

    >
    > E
    >
    >
    Gennady Bystritksy, Jan 6, 2005
    #10
  11. Howard Lewis Ship

    Sea&Gull Guest

    Bertram Scharpf wrote:
    > Am Donnerstag, 06. Jan 2005, 18:32:52 +0900 schrieb Dave Thomas:
    >
    >>On Jan 6, 2005, at 3:17 AM, Bertram Scharpf wrote:
    >>
    >>
    >>>>Thanks ... there it is, plain as day, on page 345 of PickAxe 2nd
    >>>>edition.
    >>>
    >>>Sorry, where are the page numbers in the online version?
    >>>

    >>
    >>If you're looking at it online, it's probably the first edition.

    >
    >
    > What a surprise.
    >
    > Anyway, I would have liked to know, what 'next <exp>' means.
    > Never mind; in the meantime I found out.


    This C code may illustrate how "next", "break", "redo" behave
    in Ruby:

    /*****************************/
    while (condition) {
    label_redo:

    goto label_next; /* next */
    goto label_break; /* break */
    goto label_redo; /* redo */

    /* some code */

    label_next:

    }

    label_break:

    /*****************************/


    --
    s&g
    Sea&Gull, Jan 6, 2005
    #11
  12. Hi,

    Am Freitag, 07. Jan 2005, 01:41:30 +0900 schrieb Sea&Gull:
    > Bertram Scharpf wrote:
    > >Anyway, I would have liked to know, what 'next <exp>' means.
    > >Never mind; in the meantime I found out.

    >
    > This C code may illustrate how "next", "break", "redo" behave
    > in Ruby:
    >
    > while (condition) {
    > label_redo:
    >
    > goto label_next; /* next */
    > goto label_break; /* break */
    > goto label_redo; /* redo */
    >
    > /* some code */
    >
    > label_next:
    >
    > }
    >
    > label_break:
    >


    The question was not where execution continues but what
    happens with an expression given after `next'.

    I think this behaviour has to do with an other aspect:

    def f ; yield ; end
    def g ; 5.times { |i| f { break }; print i, '-' } ; end
    puts g

    So, `break' etc. do not actually leave loops but just
    communicate with the calling `yield' that does the jump, to
    the end of the surrounging loop or function, whatever comes
    next.

    Please blame me if I'm wrong.

    Bertram

    --
    Bertram Scharpf
    Stuttgart, Deutschland/Germany
    http://www.bertram-scharpf.de
    Bertram Scharpf, Jan 6, 2005
    #12
  13. On Fri, 7 Jan 2005 00:38:59 +0900, E S <> wrote:
    >
    > For just returning control, throw...catch should work, for returning
    > a value, Kernel.callcc? But Mr. Buck's solution is certainly shorter.


    Another way to do it is to rescue LocalJumpError.

    | def yield_with_return_value(*args)
    | yield *args
    | rescue LocalJumpError => e
    | e.exit_value
    | end
    |
    | def foo(&block)
    | yield_with_return_value &block
    | end

    irb(main):001:0> foo {return "hello"; "this is not returned"}
    => "hello"
    irb(main):002:0> foo {"bar"}
    => "bar"

    Sam
    Sam Stephenson, Jan 6, 2005
    #13
  14. On Thu, 6 Jan 2005 14:08:03 -0600, Sam Stephenson <> wrote:
    > Another way to do it is to rescue LocalJumpError.
    >
    > | def yield_with_return_value(*args)
    > | yield *args
    > | rescue LocalJumpError => e
    > | e.exit_value
    > | end
    > |
    > | def foo(&block)
    > | yield_with_return_value &block
    > | end
    >
    > irb(main):001:0> foo {return "hello"; "this is not returned"}
    > => "hello"
    > irb(main):002:0> foo {"bar"}
    > => "bar"


    Sorry, I should make it a bit clearer that the block's return value is caught:

    | def foo(&block)
    | value = yield_with_return_value &block
    | "baz " + value
    | end

    irb(main):001:0> foo {return "hello"; "this is not returned"}
    => "baz hello"
    irb(main):002:0> foo {"bar"}
    => "baz bar"

    Sam
    Sam Stephenson, Jan 6, 2005
    #14
  15. Howard Lewis Ship

    Sea&Gull Guest

    > The question was not where execution continues

    Sorry, I did not undestand you clearly :)

    > but what
    > happens with an expression given after `next'.


    What do you mean asking "what happens"?

    > I think this behaviour has to do with an other aspect:
    >
    > def f ; yield ; end
    > def g ; 5.times { |i| f { break }; print i, '-' } ; end
    > puts g


    *Perhaps*, your task may be solved by a tad redesign of
    control structures:

    def f(i); yield i; end

    def g
    5.times { |i|
    break if f(i){|i| i == 3}
    print i, '-'
    }
    puts "\nEnd of g"
    end

    puts g

    > So, `break' etc. do not actually leave loops


    They "leave" _current_ block.
    In the example you gave above "break" leaves
    the block "{ break }".

    > but just
    > communicate with the calling `yield'


    afaik, "yield" neither here not there.
    It does not influence on the behaviour
    of "break".

    > that does the jump, to
    > the end of the surrounging loop or function, whatever comes
    > next.
    >
    > Please blame me if I'm wrong.
    >
    > Bertram
    >


    --
    s&g
    Sea&Gull, Jan 7, 2005
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Showjumper
    Replies:
    1
    Views:
    703
    Showjumper
    Mar 19, 2005
  2. Noozer

    Block DIV within a block DIV?

    Noozer, Jan 6, 2005, in forum: HTML
    Replies:
    3
    Views:
    11,365
    Mitja
    Jan 6, 2005
  3. Andy
    Replies:
    0
    Views:
    532
  4. morrell
    Replies:
    1
    Views:
    949
    roy axenov
    Oct 10, 2006
  5. Greenhorn
    Replies:
    15
    Views:
    815
    Keith Thompson
    Mar 6, 2005
Loading...

Share This Page