[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Extrange String#=~ behaviour

Iñaki Baz Castillo

2/24/2009 7:53:00 PM

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

5 Answers

Iñaki Baz Castillo

2/24/2009 7:54:00 PM

0

Sorry, the subject must be "Strange" :)



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

7stud --

2/25/2009 2:35:00 AM

0

Iñaki Baz Castillo wrote:
> 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





--
Posted via http://www.ruby-....

lasitha

2/25/2009 7:10:00 AM

0

On Wed, Feb 25, 2009 at 8:05 AM, 7stud -- <bbxx789_05ss@yahoo.com> wrote:
> I=F1aki Baz Castillo wrote:
>> Hi, I can't understand it:
>>
>> =A0 class String
>> =A0 =A0 def =3D~ obj
>> =A0 =A0 =A0 puts "Sorry, I don't compare"
>> =A0 =A0 end
>> =A0 end
>>
>> b) =BF?
>> irb> "string" =3D~ /string/
>> 0
>>

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.ht...

Brian Candler

2/25/2009 3:39:00 PM

0

Iñaki Baz Castillo wrote:
> 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, :obj),
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)
--
Posted via http://www.ruby-....

Iñaki Baz Castillo

2/25/2009 5:30:00 PM

0

2009/2/25 Brian Candler <b.candler@pobox.com>:
> You can see that your case (b) is parsed differently as a :match3,
> bypassing the normal method dispatch (:call)

Interesting, thanks a lot.


--=20
I=C3=B1aki Baz Castillo
<ibc@aliax.net>