Proc.new and return

Since it isn't a function! :frowning: Now, it can return sometimes -- if it's in a
function defition. And you can see that it could come in handy:

def slow_include arr, el
  arr.each do |e|
    return true if e == el
  end
  false
end

p slow_include([1, 2, 3], 3)
p slow_include([1, 2, 3], 4)

Result:

true
false

(of course, you can just use [1, 2, 3].include?(3), but this is for demo)
So, the block there returns from the function, like you'd expect. It's up to
the controlling function (Array#each in this case) to select a return value.
For instance:

[2, 4, 6].map {|q| return q * 2}

What's the expected output? Do we simply get "4" as the entire evaluation?
Remember that Array#map itself is supposed to return a value (the array with
values mapped!). So, blocks can't really return anything - it makes no
sense.

HTH,
Arlen

···

On Thu, Feb 28, 2008 at 11:39 PM, S2 <email@fin.ta> wrote:

I am sure this is a really easy question for most of you, but i was not
able to find an answer to this, or to understand the difference between
this two:

$ irb
irb(main):001:0> a = Proc.new {true}
=> #<Proc:0xb7cae308@(irb):1>
irb(main):002:0> b = a.call
=> true
irb(main):003:0> a = Proc.new {return true}
=> #<Proc:0xb7c9f768@(irb):3>
irb(main):004:0> b = a.call
LocalJumpError: unexpected return
        from (irb):3
        from (irb):4:in `call'
        from (irb):4
        from :0

why can't a block return something?

Excellent. :slight_smile: Glad we could help. [I speak too on Jari's behalf here, it
seems. I'm sure he's glad too. :)]

Arlen

···

On Fri, Feb 29, 2008 at 12:15 AM, S2 <non.sto.gioando@nien.te> wrote:

with your post and that of Jari i now understand:

irb(main):001:0> [2, 4, 6].map {|q| return q * 2}
LocalJumpError: unexpected return
        from (irb):1
        from (irb):1:in `map'
        from (irb):1

as expected. but if i put it inside a method

irb(main):002:0> def hello
irb(main):003:1> [2, 4, 6].map {|q| return q * 2}
irb(main):004:1> end
=> nil
irb(main):005:0> hello
=> 4

as expected. but if i put it inside a method

AFAIK the way return inside a block works has changed in ruby 1.9
though (it then returns from the block).

Arlen Cuss wrote:

Remember that Array#map itself is supposed to return a value (the array
with values mapped!). So, blocks can't really return anything - it makes no
sense.

Blocks return the value of the last expression in them (or, if you break from
the block, they return the value given to break, the same way return works
for methods). What the yielding method does with that return value depends,
as you say, on the method, but you can't say that blocks don't return
anything.

HTH,
Sebastian

···

--
Jabber: sepp2k@jabber.org
ICQ: 205544826

Hi,

> as expected. but if i put it inside a method

AFAIK the way return inside a block works has changed in ruby 1.9
though (it then returns from the block).

Hmm... I don't see this behaviour, but I may be out of date.

irb(main):004:0> RUBY_VERSION
=> "1.9.0"
irb(main):005:0> Proc.new {return true}.call
LocalJumpError: unexpected return
        from (irb):5:in `block (3 levels) in irb_binding'
        from (irb):5:in `call'
        from (irb):5
        from /usr/lib/ruby/1.9/irb.rb:150:in `block (2 levels) in
eval_input'
        from /usr/lib/ruby/1.9/irb.rb:259:in `signal_status'
        from /usr/lib/ruby/1.9/irb.rb:147:in `block in eval_input'
        from /usr/lib/ruby/1.9/irb.rb:146:in `eval_input'
        from /usr/lib/ruby/1.9/irb.rb:70:in `block in start'
        from /usr/lib/ruby/1.9/irb.rb:69:in `catch'
        from /usr/lib/ruby/1.9/irb.rb:69:in `start'
        from /usr/bin/irb1.9:13:in `<main>'
irb(main):006:0>

I can't find any relevant documentation that says it should be otherwise.

Arlen.

···

On Fri, Feb 29, 2008 at 12:19 AM, ThoML <micathom@gmail.com> wrote:

ThoML wrote:

AFAIK the way return inside a block works has changed in ruby 1.9
though (it then returns from the block).

Not in my copy:

irb(main):003:0> a = Proc.new {return true}
=> #<Proc:0x3ccda0@(irb):3>
irb(main):004:0> a.call
LocalJumpError: unexpected return
  from (irb):3:in `block (4 levels) in irb_binding'
  from (irb):4:in `call'
  from (irb):4
  from /Users/bush/Src/Ruby/Ruby1.9/lib/ruby/1.9.0/irb.rb:149:in `block
(2 levels) in eval_input'
  from /Users/bush/Src/Ruby/Ruby1.9/lib/ruby/1.9.0/irb.rb:262:in
`signal_status'
  from /Users/bush/Src/Ruby/Ruby1.9/lib/ruby/1.9.0/irb.rb:146:in `block
in eval_input'
  from /Users/bush/Src/Ruby/Ruby1.9/lib/ruby/1.9.0/irb.rb:145:in
`eval_input'
  from /Users/bush/Src/Ruby/Ruby1.9/lib/ruby/1.9.0/irb.rb:69:in `block
in start'
  from /Users/bush/Src/Ruby/Ruby1.9/lib/ruby/1.9.0/irb.rb:68:in `catch'
  from /Users/bush/Src/Ruby/Ruby1.9/lib/ruby/1.9.0/irb.rb:68:in `start'
  from ../Ruby1.9/bin/irb:12:in `<main>'

ruby 1.9.0 (2008-02-21 revision 15557) [i686-darwin9.1.0]

···

--
Posted via http://www.ruby-forum.com/\.

so in 1.9
Proc.new { true }
and
Proc.new { return true }
are the same?

Okay, it seems I mixed something up here. I think what I actually
referred to (I have to admit this currently is as unclear as it is to
you) probably is the change that proc has undergone.

    def foo(y)
        x = lambda {|x| return x}
        x.call(y)
        return y * 2
    end

    def bar(y)
        x = proc {|x| return x}
        x.call(y)
        return y * 2
    end

    p [foo(1), bar(1)]

With ruby19 you get [2, 1]. With ruby18 it's [2, 2].

Hi,

Blocks return the value of the last expression in them (or, if you break from
the block, they return the value given to break, the same way return works
for methods). What the yielding method does with that return value depends,
as you say, on the method, but you can't say that blocks don't return
anything.

Yes, you're right - I guess what I was trying to say is that you can't
have some `return n' or `break n' and *always* expect the return value
(of the expression including the block) will be `n' - it'll be
interpreted by the the actual function that takes the block first (or
in the case of return, break out of the function).

def some_case
  a = yield * 2
  a + 5
end

=> nil

some_case {break 32}

=> 32

some_case {32}

=> 69

It's kinda a moot/uninteresting point I'm taking now, though. However,
it was new news to meet the semantics of `proc' differed from Proc.new
so radically! Thanks guys.

Arlen

···

On Fri, Feb 29, 2008 at 2:33 AM, Sebastian Hungerecker <sepp2k@googlemail.com> wrote:

With ruby19 you get [2, 1]. With ruby18 it's [2, 2].

In 1.9 'proc {}' is the same than 'Proc.new {}', this was not the case
with 1.8.6

Guy Decoux

it was new news to meet the semantics of `proc' differed from Proc.new
so radically!

Well, that was my point and what my example was supposed to
demonstrate:
in ruby18, proc is a synonym for lambda but in ruby19 it's an alias
for
Proc.new.

http://eigenclass.org/hiki/Changes+in+Ruby+1.9#l47

Regards,
Thomas.