Extrange String#=~ behaviour

  • Thread starter Iñaki Baz Castillo
  • Start date
I

Iñaki Baz Castillo

Hi, I can't understand it:

class String
def =3D~ obj
puts "Sorry, I don't compare"
end
end


a) OK
irb> "string" =3D~ 1234
Sorry, I don't compare
nil

b) =C2=BF?
irb> "string" =3D~ /string/
0

c) OK
irb> "string".send:)"=3D~", 1234)
Sorry, I don't compare
nil

d) OK
irb> "string".send:)"=3D~", /string/)
Sorry, I don't compare
nil


Could I know why case "b" perform the normal regexp comparission instead of=
=20
invoking the re-defined String#=3D~ method??

Thanks.


=2D-=20
I=C3=B1aki Baz Castillo
 
7

7stud --

Iñaki Baz Castillo said:
Hi, I can't understand it:

class String
def =~ obj
puts "Sorry, I don't compare"
end
end

b) ¿?
irb> "string" =~ /string/
0

Could I know why case "b" perform the normal regexp comparission instead
of
invoking the re-defined String#=~ method??

To me that suggests that String#=~ calls Regexp#=~. However, I am
having no luck proving that. I can't even override Regexp#=~:

class Regexp
def =~(obj)
puts "goodbye"
end
end

puts /string/ =~ "string" #0
 
L

lasitha

Turns out using Regexp.new behaves as expected:

07> "string" =3D~ Regexp.new('string')
Sorry, I don't compare
--> nil
class Regexp
=A0def =3D~(obj)
=A0 =A0puts "goodbye"
=A0end
end

puts /string/ =3D~ "string" =A0#0

In this case too:

08> Regexp.new('string') =3D~ "string"
goodbye
--> nil

Ruby 1.9 rdoc for Regexp#=3D~ hints at special treatment for regexp literal=
s [1]:
"This assignment is implemented in the Ruby parser. So a regexp
literal is required for the assignment. The assignment is not occur if
the regexp is not a literal."
But that is in the context of assigning to ?<var> type named captures
within a regexp on the LHS, so i don't know if it's relevant.

Hope someone who knows the implementation can shed more light.

Cheers,
lasitha.

[1] http://ruby-doc.org/core-1.9/classes/Regexp.html#M001214
 
B

Brian Candler

Iñaki Baz Castillo said:
Could I know why case "b" perform the normal regexp comparission instead
of
invoking the re-defined String#=~ method??

ParseTree gem may help you.

$ cat strange.rb
class String
def =~ obj
puts "Sorry, I don't compare"
end
end

r1 = "string" =~ 1234
r2 = "string" =~ /string/
r3 = "string".send:)"=~", 1234)
r4 = "string".send:)"=~", /string/)

$ parse_tree_show strange.rb
s:)block,
s:)class,
:String,
nil,
s:)scope,
s:)defn,
:=~,
s:)scope,
s:)block,
s:)args, :eek:bj),
s:)fcall, :puts, s:)array, s:)str, "Sorry, I don't
compare")))))))),
s:)lasgn, :r1, s:)call, s:)str, "string"), :=~, s:)array, s:)lit,
1234)))),
s:)lasgn, :r2, s:)match3, s:)lit, /string/), s:)str, "string"))),
s:)lasgn,
:r3,
s:)call, s:)str, "string"), :send, s:)array, s:)lit, :=~), s:)lit,
1234)))),
s:)lasgn,
:r4,
s:)call,
s:)str, "string"),
:send,
s:)array, s:)lit, :=~), s:)lit, /string/)))))
$

You can see that your case (b) is parsed differently as a :match3,
bypassing the normal method dispatch :)call)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top