1

当通过对象调用该方法时,我正在使用该方法返回的最后一个表达式。

使用以下代码的概念。

class Simple
  def foo
    2 + 2
  end
end
#=> nil
simple = Simple.new
#=> #<Simple:0x11eb390>
simple.foo
#=> 4

但是为什么下面的代码返回这样的编码值而不是15and 20

class Fixnum
  def to_s
    self + 5
  end
end
#=> nil
puts 10
#<Fixnum:0x000015>
#=> nil
puts 15
#<Fixnum:0x00001f>
#=> nil

任何人都可以在这里帮助我理解这个概念吗?

编辑:

class Fixnum
  def to_s
    self + 5
  end
end
#=> nil
10.to_s
#=> #<Fixnum:0x000029>

同样的结果。

4

2 回答 2

3

的合同to_s要求您返回一个String. 但是,您正在返回一个Fixnum. 如果您违反合同,可能会发生各种奇怪的事情。

如果您String从您的to_s方法中正确返回 a ,那么一切都会按您的预期进行:

class Fixnum
  def to_s
    "#{self + 5}"
  end
end

puts 10
# SystemStackError: stack level too deep

好吧,“一切正常”可能有点误导。但是,正如您所看到的,一切都按您的预期发生:调用putson to_s10添加510返回15,然后调用to_son 15,添加5返回20,然后调用to_s等等20

class Fixnum
  orig_to_s = public_instance_method(:to_s)

  define_method(:to_s) do
    orig_to_s.bind(self + 5).()
  end
end

puts 10
# 15

现在,一切都按预期工作。

于 2013-02-27T15:07:39.027 回答
0

如果你将 5 添加到 self,你会得到另一个 Fixnum。

当您打印已修改 to_s 以不显示结果的 Fixnum 时,您开始看到结果对象而不是 fixnum 的值。

于 2013-02-27T14:47:35.007 回答