Message from discussion
Kernel#gsub not working properly with a block
Received: by 10.224.69.218 with SMTP id a26mr216578qaj.23.1300645343563;
Sun, 20 Mar 2011 11:22:23 -0700 (PDT)
X-BeenThere: rubinius-dev@googlegroups.com
Received: by 10.224.207.201 with SMTP id fz9ls1052348qab.3.p; Sun, 20 Mar 2011
11:22:22 -0700 (PDT)
Received: by 10.224.198.8 with SMTP id em8mr207039qab.33.1300645342772;
Sun, 20 Mar 2011 11:22:22 -0700 (PDT)
Date: Sun, 20 Mar 2011 11:22:21 -0700 (PDT)
From: "Josep M. Bach" <josep.m.b...@gmail.com>
Reply-To: rubinius-dev@googlegroups.com
To: rubinius-dev@googlegroups.com
Message-ID: <28015940.637.1300645341989.JavaMail.geo-discussion-forums@vbyc22>
Subject: Kernel#gsub not working properly with a block
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_Part_635_4991649.1300645341986"
------=_Part_635_4991649.1300645341986
Content-Type: multipart/alternative;
boundary="----=_Part_636_8568458.1300645341986"
------=_Part_636_8568458.1300645341986
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
Hi there!
The following spec does not pass on rbx (in
spec/ruby/core/kernel/gsub_spec.rb#78):
describe "Kernel#gsub with pattern and block" do
it "acts similarly to using $_.gsub" do
$_ = "olleh dlrow"
gsub(/(\w+)/){ $1.reverse }
$_.should == "hello world"
end
end
Trying to fix this one, I found that there is a comparison of replacement
(in this case it is nil, because gsub is passed a block instead of a
replacement string) with undefined, which always evaluates to false (even if
it is nil). Since I don't know really well what `undefined` is, I've first
tried comparing replacement to nil, which seems to work (in
kernel/common/string.rb#902):
def gsub(pattern, replacement=undefined)
# ...
if replacement.nil? # was if replacement == undefined
Now the problem is that, when evaling the block { $1.reverse }, $1 is nil.
Upon further inspection, This happens just before evaling the block, where
Regexp's last match is (unsuccessfully) set to the intended match data (same
file, #939):
if use_yield
# Although `match` contains actual match data,
Regexp.last_match = match
# Here Regexp.last_match is nil.
# So this block evaluation will fail when trying to do nil.reverse
val = yield(match.to_s)
I've tried it in the rbx console, so it seems Regexp.last_match=(matchdata)
(although it returns the passed matchdata) does nothing to Regexp.last_match
(it keeps previous matched data, or nil if it was nil).
I've checked the regexp.cpp file but I'm no expert there, so I can't tell
what's wrong....
Any thoughts?
------=_Part_636_8568458.1300645341986
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div>Hi there!</div><div><br></div>The following spec does not pass on rbx =
(in <font class=3D"Apple-style-span" face=3D"'courier new', monospace">spec=
/ruby/core/kernel/gsub_spec.rb#78)</font>:<div><blockquote><font class=3D"A=
pple-style-span" face=3D"'courier new', monospace"> describe "Ke=
rnel#gsub with pattern and block" do<br> it "acts similar=
ly to using $_.gsub" do<br> $_ =3D "olleh dlrow"<b=
r> gsub(/(\w+)/){ $1.reverse }<br> &nb=
sp; $_.should =3D=3D "hello world"<br> end<br> =
; end</font></blockquote></div><div>Trying to fix this one, I found th=
at there is a comparison of replacement (in this case it is nil, because gs=
ub is passed a block instead of a replacement string) with undefined, which=
always evaluates to false (even if it is nil). Since I don't know really w=
ell what `undefined` is, I've first tried comparing replacement to nil, whi=
ch seems to work (in kernel/common/string.rb#902):</div><div><br></div><div=
><blockquote> <font class=3D"Apple-style-span" face=3D"'courier new', =
monospace"> def gsub(pattern, replacement=3Dundefined)<br> =
# ...<br> if replacement.nil? # was if replacement=
=3D=3D undefined</font> </blockquote><div>Now the problem is that, wh=
en evaling the block <font class=3D"Apple-style-span" face=3D"'courier new'=
, monospace">{ $1.reverse }, $1</font> is nil. Upon further inspection=
, This happens just before evaling the block, where Regexp's last match is =
(unsuccessfully) set to the intended match data (same file, #939):</div><di=
v><blockquote><font class=3D"Apple-style-span" face=3D"'courier new', monos=
pace"> if use_yield<br> =
# Although `match` contains actual match data,<br> =
Regexp.last_match =3D match<br> &nb=
sp;# Here Regexp.last_match is nil.<br> <br=
> # So this block evaluation will fail when=
trying to do nil.reverse<br> val =3D yield=
(match.to_s)</font></blockquote></div><div>I've tried it in the rbx console=
, so it seems Regexp.last_match=3D(matchdata) (although it returns the pass=
ed matchdata) does nothing to Regexp.last_match (it keeps previous matched =
data, or nil if it was nil).</div><div><br></div><div>I've checked the rege=
xp.cpp file but I'm no expert there, so I can't tell what's wrong....</div>=
<div><br></div><div>Any thoughts?</div><blockquote> </blockquote><div>=
</div></div>
------=_Part_636_8568458.1300645341986--
------=_Part_635_4991649.1300645341986--