0

Ruby's Array class has the built-in method to_s that can turn the array into a string. This method also works with multidimensional array. How is this method implemented?

I want to know about it, so I can reimplement a method my_to_s(ary) that can take in a multidimensional and turn it to a string. But instead of returning a string representation of the object like this

[[[1,2,3, Person.new('Mary')]],[4,5,6,7], Person.new('Paul'),2,3,8].to_s
# [[[1, 2, 3, #<Person:0x283fec0 @name='Mary']], [4, 5, 6, 7], #<Person:0x283fe30 @name='Paul'>, 2, 3, 8]   

my_to_s(ary) should call the to_s method on these objects, so that it returns

my_to_s([[[1,2,3, Person.new('Mary')]],[4,5,6,7], Person.new('Paul'),2,3,8])
# [[[1, 2, 3, Student Mary]], [4, 5, 6, 7], Student Paul>, 2, 3, 8]
1
  • 1
    I actually believe that you just want to override Person#to_s to return "Student #{self.name}" string. Commented Jun 20, 2017 at 10:35

1 Answer 1

2

For nested elements it just calls to_s respectively:

def my_to_s
  case self
  when Enumerable then '[' << map(&:my_to_s).join(', ') << ']'
  else 
    to_s # or my own implementation
  end
end

This is a contrived example, that nearly works, if this my_to_s method is defined on the very BasicObject.


As suggested by Stefan, one might avoid monkeypathing:

def my_to_s(object)
  case object
  when Enumerable then '[' << object.map { |e| my_to_s(e) }.join(', ') << ']'
  else 
    object.to_s # or my own implementation
  end
end

More OO approach:

class Object
  def my_to_s; to_s; end
end

class Enumerable
  def my_to_s
    '[' << map(&:my_to_s).join(', ') << ']'
  end
end

class Person
  def my_to_s
    "Student #{name}"
  end
end
Sign up to request clarification or add additional context in comments.

7 Comments

Or object.map { |o| my_to_s(o) } to avoid the monkey patching.
And you probably want to surround the nested output with '[' and ']'.
For more object oriented approach, you could alias my_to_s to to_s for Object and override it in Enumerable
@Stefan alias_method works for me. class Object; alias_method :my_to_s, :to_s; end; 5.my_to_s"#<Fixnum:0x0000000000000b>". Ah! It works, but it strictly maps to Object#to_s.
@Stefan yes, it looks like the polymorphism is broken and it just produces a “hardlink” to Object#to_s. Funny.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.