views:

133

answers:

2

Hi,

maybe someone knows the technical answer to the following behaviour:

s = "hello world!"
s == s.upcase
# =>false, because "hello world!" != "HELLO WORLD!"
s == s.upcase!
#=>true, because s is changed before comparison?

Thanks in advance,

Mathias

+4  A: 

This would happen in every language, think of it this way

AreEqual(s, s.upcase())

vs.

AreEqual(s, s.upcase!())

In both cases, the upcase(!) function has to be called before it can be passed to AreEqual, and in the upcase!() case, it actually changes the value of s. upcase() returns a new string with the uppercased version of s.

Paul Betts
Hmm, right. I forgot == is a method, too. So the above behaviour makes sense. Thank you! :)
Mathias
Even if the equality comparison weren't a method--even if it were an operator--it would still make sense. The explanation here is an analogy.
Jonathan Feinberg
Equality is definitely a method in Ruby, try typing "foo".== "bar" into irb :)
Paul Betts
+3  A: 

Don't do that.

upcase! returns either the upcased string or nil if no changes were made, so the result of that comparison will always be false after the first time. But it's a very bad idea to depend on side-effect semantics that way.

Jonathan Feinberg