0

How do you change what is printed with puts when an object is referenced?

Consiser the following code:

class MyClass
    attr_accessor :var
    def initialize(var)
        @var = var
    end
    # ...
end
obj = MyClass.new("content")
puts obj # Prints #<MyClass:0x0000011fce07b4a0> but I want it to print "content"

I imagine that there is an operator that you can overload (or something similar), but I don't know what it's called so I have no clue what to search for to find the answer.

PKP
  • 17
  • 5
  • It depends on how the printing is invoked. In your example, you are using `puts`, which invokes the method `to_s` on the object. If you had written `p obj`, it would have invoked the method `inspect` on it. This is explained in the documentation of i.e. `puts`. – user1934428 Jan 09 '23 at 12:02
  • Perfect! Thanks! I should have thought of looking in the puts documentation... :D – PKP Jan 09 '23 at 12:21

2 Answers2

1
class MyClass
  attr_accessor :var
  def initialize(var)
    @var = var
  end

  def to_s
    @var
  end
end

obj = MyClass.new("content")
puts obj # Prints "content"
Yahor Barkouski
  • 1,361
  • 1
  • 5
  • 21
1

Quote from the documentation of puts:

puts(*objects)nil

Writes the given objects to the stream, which must be open for writing; returns nil. Writes a newline after each that does not already end with a newline sequence. [...]

Treatment for each object:

  • String: writes the string.
  • Neither string nor array: writes object.to_s.
  • Array: writes each element of the array; arrays may be nested.

That means: The object you pass to puts is not a string, therefore, Ruby will call to_s on that object before outputting the string to IO. Because your object has no to_s method implemented, the default implementation from Object#to_s.

To return a customize output, just add your own to_s method to your class like this:

class MyClass
  attr_accessor :var

  def initialize(var)
    @var = var
  end

  def to_s
    var
  end
end
spickermann
  • 100,941
  • 9
  • 101
  • 131