10
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?

Clint Pachl
  • 10,848
  • 6
  • 41
  • 42

3 Answers3

16

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.

matt
  • 78,533
  • 8
  • 163
  • 197
  • RE overriding #to_s: As of Ruby 2.0.0 the docs clarify the behavior: "First tries to call its to_str method, then its to_s method.". This is why overriding #to_s has no effect -- because Ruby first invokes .to_str on the MyString object, which hasn't been overridden in the example above. – Jordan Brough Feb 18 '20 at 17:21
5

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>
Clint Pachl
  • 10,848
  • 6
  • 41
  • 42
2

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

UncleGene
  • 2,132
  • 16
  • 19