Proc.new and return

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@:1(irb)
irb(main):002:0> b = a.call
=> true
irb(main):003:0> a = Proc.new {return true}
=> #Proc:0xb7c9f768@:3(irb)
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?

On Thu, Feb 28, 2008 at 11:39 PM, S2 [email protected] wrote:

=> #Proc:0xb7c9f768@:3(irb)
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?

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

S2 wrote:

=> #Proc:0xb7c9f768@:3(irb)
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?

The result you’re getting is for having a return keyword outside a
method. If you instead do this, return will work.

def my_proc
a = Proc.new {return true}
puts “Call it”
a.call
puts “This will never happen”
false
end

puts my_proc

=>
Call it
true

Best regards,

Jari W.

Arlen C. wrote:

Since it isn’t a function!

doh! of course. i feel really stupid now :slight_smile:

[cut of interesting stuff]

So, blocks can’t really return anything - it makes no
sense.

thanks

On Fri, Feb 29, 2008 at 12:15 AM, S2 [email protected] wrote:

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

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

Arlen C. wrote:

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

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

ThoML wrote:

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

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

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@:3(irb)
irb(main):004:0> a.call
LocalJumpError: unexpected return
from (irb):3:in block (4 levels) in irb_binding' from (irb):4:incall’
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:insignal_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:ineval_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:incatch’
from /Users/bush/Src/Ruby/Ruby1.9/lib/ruby/1.9.0/irb.rb:68:in start' from ../Ruby1.9/bin/irb:12:in

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

Hi,

On Fri, Feb 29, 2008 at 12:19 AM, ThoML [email protected] wrote:

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
irb(main):006:0>

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

Arlen.

“T” == ThoML [email protected] writes:

T> 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

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].

Arlen C. 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

Hi,

On Fri, Feb 29, 2008 at 2:33 AM, Sebastian H.
[email protected] wrote:

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

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.