# Extrange String#=~ behaviour

**URL:** <https://www.ruby-forum.com/t/extrange-string-behaviour/161260>\
**Category:** Ruby\
**Created:** [February 24, 2009, 8:54pm UTC](https://www.ruby-forum.com/t/extrange-string-behaviour/161260 "2009-02-24T20:54:20Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [February 24, 2009, 8:54pm UTC](https://www.ruby-forum.com/t/extrange-string-behaviour/161260/1 "2009-02-24T20:54:20Z")

</div>

Hi, I can’t understand it:

class String  
def =~ obj  
puts “Sorry, I don’t compare”  
end  
end

a) OK  
irb\> “string” =~ 1234  
Sorry, I don’t compare  
nil

b) Â¿?  
irb\> “string” =~ /string/  
0

c) OK  
irb\> “string”.send(:"=~", 1234)  
Sorry, I don’t compare  
nil

d) OK  
irb\> “string”.send(:"=~", /string/)  
Sorry, I don’t compare  
nil

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

Thanks.

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [February 24, 2009, 8:54pm UTC](https://www.ruby-forum.com/t/extrange-string-behaviour/161260/2 "2009-02-24T20:54:55Z")

</div>

Sorry, the subject must be “Strange” 🙂

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [February 25, 2009, 3:35am UTC](https://www.ruby-forum.com/t/extrange-string-behaviour/161260/3 "2009-02-25T03:35:44Z")

</div>

IÃ±aki Baz C. 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

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [February 25, 2009, 8:11am UTC](https://www.ruby-forum.com/t/extrange-string-behaviour/161260/4 "2009-02-25T08:11:27Z")

</div>

On Wed, Feb 25, 2009 at 8:05 AM, 7stud – [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> > irb\> “string” =~ /string/  
> > 0

Turns out using Regexp.new behaves as expected:

07\> “string” =~ Regexp.new(‘string’)  
Sorry, I don’t compare  
 → nil

> class Regexp  
> def =~(obj)  
> puts “goodbye”  
> end  
> end
> 
> puts /string/ =~ “string” #0

In this case too:

08\> Regexp.new(‘string’) =~ “string”  
goodbye  
 → nil

Ruby 1.9 rdoc for Regexp#=~ hints at special treatment for regexp  
literals [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 ? 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] [class Regexp - RDoc Documentation](http://ruby-doc.org/core-1.9/classes/Regexp.html#M001214)

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [February 25, 2009, 6:31pm UTC](https://www.ruby-forum.com/t/extrange-string-behaviour/161260/5 "2009-02-25T18:31:56Z")

</div>

2009/2/25 Brian C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

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

Interesting, thanks a lot.

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [February 25, 2009, 4:39pm UTC](https://www.ruby-forum.com/t/extrange-string-behaviour/161260/6 "2009-02-25T16:39:53Z")

</div>

IÃ±aki Baz C. 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)
