Project

General

Profile

Actions

Bug #18432

closed

case ... when bug if add a extra comma on the end of condition.

Added by zw963 (Wei Zheng) 8 months ago. Updated 7 months ago.

Status:
Rejected
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:106815]

Description

I will describe how this bug happen for me.

  1. I have code like this at first, it works!
type = 'aaa'

case type
when 'aaa'
  x = 100
  p x
when 'bbb'
  x = 100
  p x
end
# => 100
  1. Because the code in when case 'aaa' or 'bbb', all code same, so, i do some refactor, it still work, like this:
type = 'aaa'

case type
when 'aaa', 'bbb'
  x = 100
  p x
end
# => 100
  1. Then, logic is changes, i need split 'aaa' and 'bbb' back to original form, somethings is wrong!
type = 'aaa'

case type
when 'aaa',
  x = 100
  p x
when 'bbb'
  x = 200
  p x
end

# => nil

What i expected is raise syntax error, let me find this issue quickly, but, it just ignore silently.

  1. In fact, it even no syntax error raised when i remove the second when.
type = 'aaa'

case type
when 'aaa',
  x = 100
  p x
 'bbb'
  x = 200
  p x
# nil
# 200
end

Following is disam ouput for case 3

== disasm: #<ISeq:<main>@1.rb:1 (1,0)-(10,3)> (catch: FALSE)
local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 2] type@0     [ 1] x@1
0000 putstring                              "aaa"                     (   1)[Li]
0002 setlocal_WC_0                          type@0
0004 getlocal_WC_0                          type@0                    (   3)[Li]
0006 dup                                                              (   4)
0007 putobject                              "aaa"
0009 checkmatch                             2
0011 branchif                               33
0013 dup                                                              (   5)
0014 putobject                              100
0016 dup
0017 setlocal_WC_0                          x@1
0019 checkmatch                             2
0021 branchif                               33
0023 dup                                                              (   7)
0024 putobject                              "bbb"
0026 checkmatch                             2
0028 branchif                               40
0030 pop                                                              (   3)
0031 putnil
0032 leave                                                            (   9)
0033 pop                                                              (   4)
0034 putself                                                          (   6)[Li]
0035 getlocal_WC_0                          x@1
0037 opt_send_without_block                 <calldata!mid:p, argc:1, FCALL|ARGS_SIMPLE>
0039 leave                                                            (   9)
0040 pop                                                              (   7)
0041 putobject                              200                       (   8)[Li]
0043 setlocal_WC_0                          x@1
0045 putself                                                          (   9)[Li]
0046 getlocal_WC_0                          x@1
0048 opt_send_without_block                 <calldata!mid:p, argc:1, FCALL|ARGS_SIMPLE>

Updated by mame (Yusuke Endoh) 8 months ago

case type
when 'aaa',
  x = 100
  p x
end

is parsed as

case type
when 'aaa', (x = 100)
  p x
end

which is (almost) equivalent to

if 'aaa' === type || ((x = 100) === type)
  p x
end

. If 'aaa' === type evaluates to true, (x = 100) is not executed. Thus, x is uninitialized, so it is nil by default.

Updated by zw963 (Wei Zheng) 8 months ago

mame (Yusuke Endoh) wrote in #note-1:

case type
when 'aaa',
  x = 100
  p x
end

is parsed as

case type
when 'aaa', (x = 100)
  p x
end

which is (almost) equivalent to

if 'aaa' === type || ((x = 100) === type)
  p x
end

. If 'aaa' === type evaluates to true, (x = 100) is not executed. Thus, x is uninitialized, so it is nil by default.

Yes, i see now, but this behavior is a little oddness, from programming language perspective, this default behavior not good.

e.g. i add a binding.irb, like this, it so strange.

From: 1.rb @ line 7 :

     2: 
     3: case type
     4: when 'aaa',
     5:   x = 100
     6:   p x
 =>  7:   binding.irb
     8: when 'bbb'
     9:   x = 200
    10:   p x
    11: end

3.0.3 :001 > x
 => nil 


Actions #3

Updated by jeremyevans0 (Jeremy Evans) 7 months ago

  • Status changed from Open to Rejected
Actions

Also available in: Atom PDF