【问题标题】:Why does method not returning its last expression when it is called?为什么方法在调用时不返回其最后一个表达式?
【发布时间】:2013-02-27 14:43:33
【问题描述】:

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

使用以下代码的概念。

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

但是为什么下面的代码返回这样的编码值而不是15和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>

同样的结果。

【问题讨论】:

    标签: ruby


    【解决方案1】:

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

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

    class Fixnum
      def to_s
        "#{self + 5}"
      end
    end
    
    puts 10
    # SystemStackError: stack level too deep
    

    好吧,“一切正常”可能有点误导。但是,正如您所见,一切发生正如您所料:puts 在10 上调用to_s,这会将5 添加到10,返回15,然后它在15 上调用to_s,添加5 返回20,然后在20 上调用to_s 等。

    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
    

    现在,一切正常。

    【讨论】:

    【解决方案2】:

    如果你给自己加 5,你会得到另一个 Fixnum。

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

    【讨论】:

      猜你喜欢
      • 2017-03-18
      • 2013-09-06
      • 2016-05-07
      • 1970-01-01
      • 2013-12-25
      • 2021-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多