From: nobu.nakada@... Date: 1999-06-16T07:58:38+09:00 Subject: [ruby-dev:7122] return value from ||= for [] and accessor はじめまして、中田といいます。 表記の件、以下のように既に値がセットされていた場合戻り値が nil になり ますが、String#sub! みたいに変更が起きたことを返すという仕様なんでしょう か。 a = [] a[0] ||= true # => true a[0] ||= true # => nil class Foo; attr_accessor :x end a = Foo.new a.x ||= true # => true a.x ||= true # => nil `x ||= y' ≡ `x = x || y' と考えれば、やはりここはレシーバが返って来た ほうがいいんじゃないかと思いまして、とりあえずパッチを作ってみました。つ いでに &&= についても、代入が起きないときには nil ではなくてレシーバの値 をそのまま返すようにしてみました。 # 余談ですが、なぜか下記のアドレスだとメールサーバにリジェクトされます。 # しかたないから Nifty の方を使ったけど…なんで? (;_;) -- /| / /| / 中田伸悦@鹿沼.栃木 _/ _/OBU. _/ _/OKADA diff --recursive --unified ruby-1.3.4-990611/eval.c ruby/eval.c --- ruby-1.3.4-990611/eval.c Fri Jun 11 15:29:46 1999 +++ ruby/eval.c Mon Jun 14 02:21:19 1999 @@ -2250,15 +2250,16 @@ rval = node->nd_args->nd_head; SETUP_ARGS(node->nd_args->nd_next); val = rb_funcall2(recv, aref, argc-1, argv); - if (node->nd_mid == 0) { /* OR */ - if (RTEST(val)) break; + switch (node->nd_mid) { + case 0: /* OR */ + if (RTEST(val)) RETURN(val); val = rb_eval(self, rval); - } - else if (node->nd_mid == 1) { /* AND */ - if (!RTEST(val)) break; + break; + case 1: /* AND */ + if (!RTEST(val)) RETURN(val); val = rb_eval(self, rval); - } - else { + break; + default: val = rb_funcall(val, node->nd_mid, 1, rb_eval(self, rval)); } argv[argc-1] = val; @@ -2274,15 +2275,16 @@ recv = rb_eval(self, node->nd_recv); val = rb_funcall(recv, id, 0); - if (node->nd_next->nd_mid == 0) { /* OR */ - if (RTEST(val)) break; + switch (node->nd_next->nd_mid) { + case 0: /* OR */ + if (RTEST(val)) RETURN(val); val = rb_eval(self, node->nd_value); - } - else if (node->nd_next->nd_mid == 1) { /* AND */ - if (!RTEST(val)) break; + break; + case 1: /* AND */ + if (!RTEST(val)) RETURN(val); val = rb_eval(self, node->nd_value); - } - else { + break; + default: val = rb_funcall(val, node->nd_next->nd_mid, 1, rb_eval(self, node->nd_value)); }