Burdette Lamar
Burdette Lamar

Reputation: 359

Is there a Ruby built-in class or module (other than String) that has method #to_str?

For some testing, I'm looking for a Ruby built-in class or module (other than String) that has method #to_str.

(I know that many have method #to_s, but that's not what I'm looking for.)

I've pored over the docs, and can't find any such.

Upvotes: 4

Views: 117

Answers (2)

Jörg W Mittag
Jörg W Mittag

Reputation: 369546

The easiest way is to ask Ruby herself:

ObjectSpace.
  each_object(Module).
  select {|mod| mod.instance_methods(false).include?(:to_str) } - 
    [String]
#=> [NameError::message]

So, it turns out the only other class that defines to_str is an internal implementation class inside NameError. Which makes sense, really, there are not that many objects in Ruby that are strings but are not instances of String.

I would expect a Ropes library (if such a thing exists) to implement to_str, for example.

Upvotes: 7

3limin4t0r
3limin4t0r

Reputation: 21130

This doesn't answer the question if there is any class that implements the #to_str method. Rather this answer focuses on:

For some testing, I'm looking for a Ruby built-in class or module (other than String) that has method #to_str.

You could create an temporary class for testing purposes that forwards all calls to the internal string.

require 'delegate'

# create an anonymous class inheriting from DelegateClass(String)
my_string_class = Class.new(DelegateClass(String))
my_string       = my_string_class.new("Hello World!")

my_string.is_a?(String)     #=> false
"Hello World!" == my_string #=> true

The reason the above comparison returns true can be found in the String documentation.

str == obj → true or false

Equality—Returns whether str == obj, similar to Object#==.

If obj is not an instance of String but responds to to_str, then the two strings are compared using obj.==.

Otherwise, returns similarly to #eql?, comparing length and content.

You could also skip the creation of the anonymous class and use SimpleDelegator instead.

my_string = SimpleDelegator.new("Hello World!")

For more info about delegators take a look at the documentation.

Upvotes: 1

Related Questions