Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Ruby, what's the difference between String() and #to_s

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?

like image 972
Clint Pachl Avatar asked Nov 13 '12 19:11

Clint Pachl


3 Answers

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.

like image 106
matt Avatar answered Dec 24 '22 09:12

matt


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>
like image 39
Clint Pachl Avatar answered Dec 24 '22 11:12

Clint Pachl


String(object) is a Kernel method that calls #to_s on the object

like image 33
UncleGene Avatar answered Dec 24 '22 09:12

UncleGene