Как объявление метода экземпляра вне класса работает в Ruby? - PullRequest
1 голос
/ 07 апреля 2019

Что ж, название вопроса может показаться неправильным, но я хочу спросить, как на самом деле работает следующий код?

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 Ответ

2 голосов
/ 07 апреля 2019

Методы, определенные вне какого-либо класса, добавляются в класс Object, который является одним из Struct предков (то есть Struct наследует все Object методы).

Попробуйте это в новом сеансе irb:

self.class
#=> Object

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

def foo
  "foo"
end
#=> :foo

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

В представленном примере вы создаете экземпляр Klass (который включает Struct и Object в своей цепочке предков), поэтому, когда создается новый экземпляр Klass, он включает все Object ' s методы, включая новый foo метод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...