Unable to override to_s in irb

I defined a function: to_s in pry, but I can't name it. Where does this method go and how can I call it?

pry(main)> def to_s pry(main)* 'hello' pry(main)* end pry(main)> to_s => "main" 

My ruby โ€‹โ€‹version is 2.1.2

After reading some answers and searching, I think I have the correct answer:

  • Where is this method?

when a method is defined in irb or pry, it goes to Object.instance_methods

 [1] pry(main)> def to_s [1] pry(main)* 'hello' [1] pry(main)* end => :to_s [2] pry(main)> def hello [2] pry(main)* 'world' [2] pry(main)* end => :hello [4] pry(main)> Object.instance_methods(false) => [:pry, :__binding__, :to_s, :hello] 
  1. How can I call him?

These new methods can be called in a new object.

 [6] pry(main)> Object.new.to_s => "hello" 

The reason I cannot call to_s at the top level is because main is the special object that the #to_s and #inspect .

 [5] pry(main)> singleton_class.instance_methods(false) => [:to_s, :inspect] 
+5
source share
4 answers

@ Anthony's answer explains the context. To define your own to_s at this level, you can do it like this:

 pry(main)> to_s => "main" pry(main)> def self.to_s pry(main)* 'hello' pry(main)* end pry(main)> to_s => "hello" 
+4
source

In fact, you are at the top level of the Object class#to_s , which, as stated in the docs:

Returns a string representing obj. By default, to_s prints an object class and encoding an object identifier. As a special case, the top-level object, which is the original ruby โ€‹โ€‹execution context of the program, returns the "main".

+3
source

Methods defined at the top level become private methods of the Object instance.

So,

 def to_s; 'hello' end 

equivalently

 class Object; private def to_s; 'hello' end end 

And messages sent without an explicit recipient are implicitly sent to self .

So,

 to_s 

equivalently

 self.to_s 

At the top level, self is an unnamed top-level object, commonly called main .

Now, if any of the main classes overrides Object#to_s , then an overridden version will be called. And in fact, to_s overridden in the singleton class main :

 method(:to_s).owner # => #<Class:#<Object:0x007fb5210c1c68>> 
+1
source

Another, however verbose way to do what you are trying to do is to manipulate the "current" class, for example:

 class << self def to_s "hello" end end 
0
source

Source: https://habr.com/ru/post/1210307/


All Articles