From: Josh Cheek Date: 2011-08-29T17:49:18+09:00 Subject: Re: String#split resets regex captures variables (Ruby 1.8.7) --000e0cd2906058743e04aba0f8dd Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable 2011/8/29 Bartosz Dziewo=C5=84ski > I think it makes sense for $1, $2 etc to change any time a regex match > is performed anywhere in Ruby, it might be even kind of useful in some > perverse scenarios. That said, you shouldn't use these if you can, > it's a Perl relic (but I admit, sometimes it's the easiest way). > > I don't, that means that if you call some method, then it can implicitly an= d unintentionally change variables you've set, and the only way to know it is to go digging through source code. You could empirically experiment with it= , but say the regex was conditionally evaluated, then you'd not know it was used unless conditions were right, meaning it might not pop up until you were in production. > There are two solutions: either bind their values to another variables: > > n =3D "a:c" > if n =3D~ /([a-z])([.:])([a-z])/ > sep =3D $2 > p [:first, :second].zip(n.split(sep)) | [[:separator, sep]] > end > > or use #match like a man: > > n =3D "a:c" > if mtc =3D n.match(/([a-z])([.:])([a-z])/) > p [:first, :second].zip(n.split(mtc[2])) | [[:separator, mtc[2]]] > end > > Another option, for more recent rubies, is to use named capture groups if "a:c" =3D~ /(?[a-z])(?[.:])(?[a-z])/ p $~.names.map(&:intern).zip($~.captures) end # >> [[:first, "a"], [:separator, ":"], [:second, "c"]] --000e0cd2906058743e04aba0f8dd--