String(1.1) == (1.1).to_s => true
String(1.1) === (1.1).to_s => true
Is there a difference between these two coercion methods? If so, can you demonstrate?
The docs for the String
method say:
Converts arg to a String by calling its to_s method.
So generally they are the same, but there are some differences – although you’re unlikely to see them for real. String()
checks the class of its parameter, and if it’s not already a String
then calls to_s
on it. Calling to_s
directly means the method is called regardless.
Consider the class:
class MyString < String
def to_s
"Overridden to_s method"
end
end
An instance of MyString
is already a String
object, so passing it as a parameter to String()
won’t do anything. Calling to_s
on it will however return Overridden to_s method
.
1.9.3p286 :010 > m = MyString.new 'my string'
=> "my string"
1.9.3p286 :011 > o = String.new 'orig string'
=> "orig string"
1.9.3p286 :012 > String o
=> "orig string"
1.9.3p286 :013 > String m
=> "my string"
1.9.3p286 :014 > o.to_s
=> "orig string"
1.9.3p286 :015 > m.to_s
=> "Overridden to_s method"
You’re unlikely ever to need to override to_s
on a String
subclass like this, in general you can treat String()
and to_s
as the same, but it might be useful to know what’s going on.
They raise different exceptions when they fail:
bo = BasicObject.new
String(bo)
TypeError: can't convert BasicObject into String
bo.to_s
NoMethodError: undefined method `to_s' for #<BasicObject:0x0003efbfd79c10>
String(object) is a Kernel method that calls #to_s on the object
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With