Bug #2226
case 文の式が省略され when 節に配列展開があるときの挙動
| Status: | Closed | Start date: | ||
|---|---|---|---|---|
| Priority: | Low | Due date: | ||
| Assignee: | % Done: | 100% |
||
| Category: | core | |||
| Target version: | 1.9.2 | |||
| ruby -v: | ruby 1.9.2dev (2009-10-22 trunk 25433) [x86_64-freebsd8.0] |
Description
ワナベと申します。
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 */
--
ワナベ
Related issues
| related to Ruby 1.8 - Bug #2468: Array expansion inside case/when gives unexpected results | Closed | 12/10/2009 |
Associated revisions
* compile.c (iseq_compile_each): fix splat condition in NODE_WHEN.
[Bug #2226]
* compile.c (iseq_compile_each): fix splat condition in NODE_WHEN.
[Bug #2226]
History
Updated by Yui NARUSE over 2 years ago
- Category set to core
- Status changed from Open to Assigned
- Assignee set to Yukihiro Matsumoto
- Target version set to 1.9.2
- ruby -v set to ruby 1.9.2dev (2009-10-22 trunk 25433) [x86_64-freebsd8.0]
Updated by _ wanabe about 2 years ago
まつもとさん(あるいはささださん?) このチケットについて、よろしければ意見をお聞きしたいのですがどうでしょうか。 (バグではない、バグだがパッチが正しくない、コミットしてよい、など) 催促するようで申し訳ありません。
Updated by Yusuke Endoh almost 2 years ago
wanabe さん 遠藤です。 2009年10月18日6:16 wanabe <s.wanabe@gmail.com>: > case 文の式が省略され、かつ when 節に配列展開があるときの挙動、 > より具体的には NODE_ARGSCAT, NODE_ARGSPUSH の > コンパイル結果が正しくないように思います。 > 通常の NODE_CASE と同じように処理するのはどうでしょうか。 2010年1月29日2:37 _ wanabe <redmine@ruby-lang.org>: > まつもとさん(あるいはささださん?) > このチケットについて、よろしければ意見をお聞きしたいのですがどうでしょうか。 > (バグではない、バグだがパッチが正しくない、コミットしてよい、など) 確かにバグだと思いますし、ワナベさんのパッチで正しいと思います。 反対もないようなので、コミットしちゃってください。 ただ、一応、以下の点が非互換になるようです。 $ ruby -ve 'case; when true, *x; p :ok; end' ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux] :ok $ ./ruby -ve 'case; when true, *x; p :ok; end' ruby 1.9.2dev (2010-04-16 trunk 27359) [i686-linux] -e:1:in `<main>': undefined local variable or method `x' for main:Object (NameError) といっても、NODE_CASE の方ではワナベさんのパッチの前から非互換な ようです。 $ ruby -ve 'case "foo"; when "foo", *x; p :ok; end' ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux] :ok $ ./ruby -ve 'case "foo"; when "foo", *x; p :ok; end' ruby 1.9.2dev (2010-04-16 trunk 27359) [i686-linux] -e:1:in `<main>': undefined local variable or method `x' for main:Object (NameError) 実害はほぼないと思うのですが、もし暇だったら見てやってください。 -- Yusuke ENDOH <mame@tsg.ne.jp>
Updated by _ wanabe almost 2 years ago
- Status changed from Assigned to Closed
- % Done changed from 0 to 100
This issue was solved with changeset r27376. _, thank you for reporting this issue. Your contribution to Ruby is greatly appreciated. May Ruby be with you.