无法覆盖irb中的to_s

时间:2015-01-03 15:03:43

标签: ruby

我在pry中定义了一个函数:to_s,但是我无法调用它。这种方法在哪里,我怎么称呼它?

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

我的红宝石版本是2.1.2

在阅读了一些答案并进行搜索之后,我想我得到了正确答案:

  1. 这种方法在哪里?
  2. 在irb或pry中定义方法时,它会转到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. 我怎么称呼它?
    2. 可以在新对象中调用这些新方法。

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

      我无法在顶级调用to_s的原因是main是定义#to_s#inspect方法的特殊对象。

      [5] pry(main)> singleton_class.instance_methods(false)
      => [:to_s, :inspect]
      

4 个答案:

答案 0 :(得分:4)

@Anony的回答解释了背景。要在此级别定义您自己的to_s,您可以这样做:

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

答案 1 :(得分:3)

您实际上处于顶级Object class#to_s方法,正如文档所述:

  

返回表示obj的字符串。默认的to_s打印出来   object的类和对象id的编码。作为一个特例,   作为Ruby的初始执行上下文的顶级对象   程序返回“main”。

答案 2 :(得分:1)

在toplevel定义的方法成为private的{​​{1}}实例方法。

所以,

Object

相当于

def to_s; 'hello' end

没有显式接收者的消息发送被隐式发送到class Object; private def to_s; 'hello' end end

所以,

self

相当于

to_s

在顶层,self.to_s 是无名的顶级对象,通常称为self

现在,如果main的任何类覆盖main,则会调用被覆盖的版本。实际上,在Object#to_s的单例类中重写了to_s

main

答案 3 :(得分:0)

另一种无可否认的方法是完成你想要做的事情,就是操纵“当前”类,如下所示:

class << self
  def to_s
    "hello"
  end
end