【问题标题】:`initialize` seems to check the arguments given to `new``initialize` 似乎检查了给`new` 的参数
【发布时间】:2016-10-14 03:37:41
【问题描述】:

我在看这段代码:

class Mo
  def new(indy, rome = 1)
    initialize(indy, rome)
  end
  def initialize(indy, rome)
    ...
  end
end

Mo.new(2)

我得到这个输出:

test.rb:6:in `initialize': wrong number of arguments (1 for 2)   (ArgumentError)

如果我将定义中rome 的默认值添加到new,它会起作用:

class Mo
  def new(indy, rome = 1)
    initialize(indy, rome)
  end
  def initialize(indy, rome = 1)
    ...
  end
end

Mo.new(2)

为什么?

【问题讨论】:

  • 你确定你“将定义中 rome 的默认值添加到 new”吗?在我看来,您已将其添加到 initialize
  • 这和new-operator有什么关系?

标签: ruby new-operator initializer


【解决方案1】:

因为Mo.new(2) 调用方法Mo.new,默认情况下调用方法Mo#initialize 使用它收到的单个参数2,但您的Mo#initialize 需要两个参数。

【讨论】:

    【解决方案2】:

    不需要new 方法,因为initialize 是分配(创建)ruby 对象的“中间件”

    class Mo
      def initialize(indy, rome = 1)
        @indy = indy
        @rome = rome
      end
    end
    i = Mo.new(2)
    

    这意味着ruby没有进入new方法

    您可以通过以下方式查看:

    puts Mo.method(:new).source_location
    # => nil
    

    但您可以在 Mo 类中覆盖 self.new

    def self.new(indy, rome = 1)
    end
    

    然后

    p Mo.method(:new).source_location
    # =>["mo.rb", 2]
    

    然后它没有进入initialize方法

    附: 这不是一个好习惯,但如果你想执行你的代码,你应该调用

    Mo.new(2).new(3)
    

    因为你的newMo 实例方法

    【讨论】:

    • 这没有回答问题。
    • 只是一个简单的问题。这主要是由于最后的“超级”调用吗?
    【解决方案3】:

    当你编写类似的代码时

    Class Foo
      def new
        ...
      end
    end
    

    您为具有类 Foo 的对象定义了一个实例方法。但是当你创建一个新实例时,你调用了一个类的方法new。如果你想重写方法Foo.new,你应该这样写:

    Class Foo
      def self.new
        ....
      end
    end
    

    但实际上,为类声明自己的方法new 是个坏主意

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 2018-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-20
      • 2015-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多