ワナベと申します。

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 */


-- 
ワナベ