Project

General

Profile

Actions

Bug #2226

closed

case 文の式が省略され when 節に配列展開があるときの挙動

Added by wanabe (_ wanabe) over 14 years ago. Updated almost 13 years ago.

Status:
Closed
Target version:
ruby -v:
ruby 1.9.2dev (2009-10-22 trunk 25433) [x86_64-freebsd8.0]
Backport:
[ruby-dev:39506]

Description

=begin
ワナベと申します。

case 文の式が省略され、かつ when 節に配列展開があるときの挙動、
より具体的には NODE_ARGSCAT, NODE_ARGSPUSH の
コンパイル結果が正しくないように思います。
通常の NODE_CASE と同じように処理するのはどうでしょうか。

$ cat test.rb
case
when *[], false
p :ng1
else
p :ok
end

case
when *false, []
p :ok
else
p :ng2
end

begin
case
when false, *nonexistent_var, false
p :ng3
else
p :ng4
end
rescue NameError
p :ok
end

$ ruby -v test.rb
ruby 1.9.2dev (2009-10-17 trunk 25387) [i386-mingw32]
:ng1
:ng2
:ng3

Index: compile.c

--- compile.c (revision 25387)
+++ compile.c (working copy)
@@ -3116,41 +3116,31 @@
ADD_INSNL(body_seq, nd_line(node), jump, endlabel);

    vals = node->nd_head;
  •  if (vals && nd_type(vals) == NODE_ARRAY) {
    
  •  if (!vals) {
    
  •  rb_bug("NODE_WHEN: must be NODE_ARRAY, but 0");
    
  •  }
    
  •  switch (nd_type(vals)) {
    
  •    case NODE_ARRAY:
     while (vals) {
         val = vals->nd_head;
         COMPILE(ret, "when2", val);
         ADD_INSNL(ret, nd_line(val), branchif, l1);
         vals = vals->nd_next;
     }
    
  •  break;
    
  •    case NODE_SPLAT:
    
  •    case NODE_ARGSCAT:
    
  •    case NODE_ARGSPUSH:
    
  •  ADD_INSN(ret, nd_line(vals), putnil);
    
  •  COMPILE(ret, "when2/cond splat", vals);
    
  •  ADD_INSN1(ret, nd_line(vals), checkincludearray, Qfalse);
    
  •  ADD_INSN(ret, nd_line(vals), pop);
    
  •  ADD_INSNL(ret, nd_line(vals), branchif, l1);
    
  •  break;
    
  •    default:
    
  •  rb_bug("NODE_WHEN: unknown node (%s)",
    
  •         ruby_node_name(nd_type(vals)));
     }
    
  •  else if (nd_type(vals) == NODE_SPLAT ||
    
  •       nd_type(vals) == NODE_ARGSCAT ||
    
  •       nd_type(vals) == NODE_ARGSPUSH) {
    
  •  NODE *val = vals->nd_head;
    
  •  if (nd_type(vals) == NODE_ARGSCAT || nd_type(vals) == NODE_ARGSPUSH) {
    
  •      NODE *vs = vals->nd_head;
    
  •      val = vals->nd_body;
    
  •      while (vs) {
    
  •  	NODE* val = vs->nd_head;
    
  •  	COMPILE(ret, "when/argscat", val);
    
  •  	ADD_INSNL(ret, nd_line(val), branchif, l1);
    
  •  	vs = vs->nd_next;
    
  •      }
    
  •  }
    
  •  ADD_INSN(ret, nd_line(val), putnil);
    
  •  COMPILE(ret, "when2/splat", val);
    
  •  ADD_INSN1(ret, nd_line(val), checkincludearray, Qfalse);
    
  •  ADD_INSN(ret, nd_line(val), pop);
    
  •  ADD_INSNL(ret, nd_line(val), branchif, l1);
    
  •  }
    
  •  else {
    
  •  rb_bug("err");
    
  •  }
     node = node->nd_next;
    
    }
    /* else */

--
ワナベ
=end


Related issues 1 (0 open1 closed)

Related to Ruby 1.8 - Bug #2468: Array expansion inside case/when gives unexpected resultsClosed12/10/2009Actions
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0