Why return(XXX) is valid within a "value = case N ..."?

Hi, the following code does not "compile":

···

-----------------------------
  def test1
    value = return("lalala")
  end
-----------------------------
=> SyntaxError: (irb):11: void value expression

Ok, it makes sense. So then, why the following does not fail?

-----------------------------
  def test2
    value = case 123
      when Fixnum
        return "returning 'Fixnum' string from method test2"
      end
    puts "method test2 ends now"
  end
--------------------------

test2

=> "returning 'Fixnum' string from method kk"

I'm using Ruby 1.9.2 and in fact I use a method like "test2" it in my
project, but it seems a bit strange for me and I would like to be sure
that it's something correct (even if IMHO it does not make sense) and
will not change in a future Ruby 1.9 version.

Thanks a lot.

--
Iñaki Baz Castillo
<ibc@aliax.net>

Hi, the following code does not "compile":

-----------------------------
def test1
value = return("lalala")
end
-----------------------------
=> SyntaxError: (irb):11: void value expression

Ok, it makes sense. So then, why the following does not fail?

-----------------------------
def test2
value = case 123
when Fixnum
return "returning 'Fixnum' string from method test2"
end
puts "method test2 ends now"
end
--------------------------
> test2
=> "returning 'Fixnum' string from method kk"

Probably because case has branches which actually return a value (even
if it is fall through and nil). Interestingly enough this does not
work with if:

11:07:59 ~$ ruby19 -c x.rb
x.rb:7: void value expression
11:08:04 ~$ cat -n x.rb
     1
     2 def a
     3 x = if rand(10) == 0
     4 99
     5 else
     6 return 55
     7 end
     8 end
11:08:07 ~$

Could be that you have found a loophole in the parser logic. :slight_smile:

I'm using Ruby 1.9.2 and in fact I use a method like "test2" it in my
project, but it seems a bit strange for me and I would like to be sure
that it's something correct (even if IMHO it does not make sense) and
will not change in a future Ruby 1.9 version.

I'd say stop using this idiom. If you use a "case" expression because
it should yield a value (i.e. "x = case...end") then I would only use
exceptions as other way out. A "return" indicates regular execution
flow which in the case of this usage of "case" would mean "have case
return a value" but not "return from the method".

If you use "case" as a control flow construct (i.e. without assigning
the result) then a "return" inside is OK and Ruby will also accept it.
Same goes for "if".

Kind regards

robert

···

On Thu, Jul 14, 2011 at 10:56 AM, Iñaki Baz Castillo <ibc@aliax.net> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Could be that you have found a loophole in the parser logic. :slight_smile:

XD

I'm using Ruby 1.9.2 and in fact I use a method like "test2" it in my
project, but it seems a bit strange for me and I would like to be sure
that it's something correct (even if IMHO it does not make sense) and
will not change in a future Ruby 1.9 version.

I'd say stop using this idiom. If you use a "case" expression because
it should yield a value (i.e. "x = case...end") then I would only use
exceptions as other way out. A "return" indicates regular execution
flow which in the case of this usage of "case" would mean "have case
return a value" but not "return from the method".

If you use "case" as a control flow construct (i.e. without assigning
the result) then a "return" inside is OK and Ruby will also accept it.
Same goes for "if".

Thanks, I'll make my code more "polite" then :slight_smile:

···

2011/7/14 Robert Klemme <shortcutter@googlemail.com>:

--
Iñaki Baz Castillo
<ibc@aliax.net>

于 2011年07月14日 17:38, Iñaki Baz Castillo 写道:

If you use a "case" expression because
> it should yield a value (i.e. "x = case...end") then I would only use
> exceptions as other way out. A "return" indicates regular execution
> flow which in the case of this usage of "case" would mean "have case
> return a value" but not "return from the method".

Remember all the block in ruby is actually a snippet ,so return from the block will return from the method which call the block.
For example,type the following code in irb

value =case 123
   when Fixnum
     return "good"
   end
LocalJumpError: unexpected return

The real reason for your question is that, everything in ruby has a value, include statements. When return statements works, it yield a value which is the result of the invocation, the assignment doesn't happen.

value=2
def test2
   value=case 123
     when Fixnum
       return 3
     end
end

test2
p value
#output
2