From: "NARUSE, Yui" Date: 2008-01-31T15:49:51+09:00 Subject: [ruby-dev:33548] block parameter of String#gsub 成瀬です。 Ruby スレッドで出ていた話題なのですが、現在の String#gsub がブロックを受 け取った時、ブロックには $& が渡されています。 "abcdefg".gsub(/(.).(.)/){|m|p m; m} "abc" "def" => "abcdefg" これだと、事実上ブロックパラメータは使い物にならないので、MatchData を渡 すようにしませんか。 "abcdefg".gsub(/(.).(.)/){|m|p m; m} # # => "abcdefg" 気になるのは互換性ですが m.to_s は 今までの $& と一致するので、 "abcdefg".gsub(/(.).(.)/){|m| m+","} はさすがにエラーが出ますが、 "abcdefg".gsub(/(.).(.)/){|m| "%s," % m} なら今まで通り動きますし、 そもそもおそらくほとんどの現在のコードは、 "abcdefg".gsub(/(.).(.)/){$&+","} でしょう。 --- string.c (revision 15354) +++ string.c (working copy) @@ -2739,7 +2739,7 @@ rb_str_sub_bang(int argc, VALUE *argv, V char *p = RSTRING_PTR(str); long len = RSTRING_LEN(str); rb_match_busy(match); - repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match))); + repl = rb_obj_as_string(rb_yield(match)); str_mod_check(str, p, len); str_frozen_check(str); rb_backref_set(match); @@ -2876,7 +2876,7 @@ str_gsub(int argc, VALUE *argv, VALUE st regs = RMATCH(match)->regs; if (iter) { rb_match_busy(match); - val = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match))); + val = rb_obj_as_string(rb_yield(match)); str_mod_check(str, sp, slen); if (bang) str_frozen_check(str); if (val == dest) { /* paranoid check [ruby-dev:24827] */ -- NARUSE, Yui DBDB A476 FDBD 9450 02CD 0EFC BCE3 C388 472E C1EA