类外部的实例方法声明在Ruby中如何工作?

时间:2019-04-07 15:39:03

标签: ruby

嗯,问题的标题似乎不合适,但我想问一下以下代码实际上是如何工作的?

class Klass < Struct.new(:x, :y, :z)
end

public
def foo
        bar
end

def inspect
        "Can't override inspect -> #{self.class}"
end

private
def bar
        [x, y, z]
end

def baz
        send(:class)
end

obj = Klass.new(1, 2, 3)

p obj.foo            # => [1, 2, 3]
p obj                # => #<struct Klass x=1, y=2, z=3>
p Klass.ancestors    # => [Klass, #<Class:0x0000563835a45600>, Struct, Enumerable, Object, Kernel, BasicObject]

现在,这似乎是一个非常糟糕的做法。但这实际上如何工作?

1 个答案:

答案 0 :(得分:2)

在任何类之外定义的方法都将添加到Object祖先之一的Struct类中(即Struct继承了所有Object方法)。

在新的irb会话中尝试以下操作:

self.class
#=> Object

self.respond_to?(:foo)
#=> false

def foo
  "foo"
end
#=> :foo

self.respond_to?(:foo)
#=> true

在提供的示例中,您创建Klass的实例(在其祖先链中包括StructObject),因此在创建新的Klass实例时,它包括所有Object的方法,包括新的foo方法。