Почему «класс» показывает «класс», когда «ancestors.include»? Класс «ложь»? - PullRequest
0 голосов
/ 08 мая 2018

У меня есть класс User, который наследуется от ApplicationRecord. Когда я проверяю User.ancestors.include?(Class), результат равен false, но для User.class результат равен Class.

Каков случай использования информации, предоставляемой методом class в таких случаях? Что это действительно говорит мне, чтобы иметь практическое применение? Кажется, это не имеет ничего общего с наследованием.

Ответы [ 4 ]

0 голосов
/ 08 мая 2018

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

class работает одинаково для каждого объекта. Вызов class для класса предоставляет ту же информацию, что и вызов class для экземпляра. Это потому, что в Ruby классы тоже являются экземплярами.

'foo'.class возвращает String, поскольку 'foo' является экземпляром String. Аналогично, User.class возвращает Class, поскольку User является экземпляром Class.

В частности, User является , а не экземпляром ApplicationRecord.

Может быть неочевидно, что User является экземпляром Class при его создании с помощью ключевого слова class:

class User < ApplicationRecord; end

Но это становится очень очевидным, когда вы создаете его явно с помощью Class.new: (оба примера дают один и тот же результат)

User = Class.new(ApplicationRecord)
User.class #=> Class

Поскольку вышеприведенное выглядит так: (используя String.new в демонстрационных целях)

foo = String.new('foo')
foo.class #=> String
0 голосов
/ 08 мая 2018

Классы в Ruby являются первоклассными объектами - каждый является экземпляром класса Class

User является объектом класса Class (который наследуется от Object). class является методом экземпляра Object. Возвращает класс объекта. Следовательно, User.class возвращает Class. У каждого объекта будет этот метод, и полезно знать, что это за объект (например, для отладки). Рассмотрим этот код:

1.class
# => Fixnum
"q".class
# => String

Причина, по которой User.ancestors не возвращает Class, заключается в том, что он возвращает модули, включенные в module. Например, Class.ancestors будет включать Class, но не User, потому что User является объектом Class, который включает в себя свои собственные модули.

0 голосов
/ 08 мая 2018

Прочитав еще одну публикацию StackOverflow , я понял, что это можно понять, только помня следующее:

  1. User класс играет двойную роль. Это играет Класс так же как Объект.
    • Как класс, он позволяет другим классам наследовать от него.
    • Как объект, он наследует метод класса полностью от класса объекта.
  2. Если бы я хотел, чтобы мой User.class вел себя по традиционным линиям (то есть User.class показывает ApplicationRecord), то я должен переопределить это следующим образом:

    class User def self.class self.superclass end end

0 голосов
/ 08 мая 2018

User это класс. Все классы являются экземплярами класса Class (т.е. User.class #=> Class). Следовательно, все методы экземпляров, определенные для Class или для предков Class, могут быть вызваны на User (то есть каждый метод экземпляра Class является методом класса User).

Например, один из методов экземпляра Class - instance_methods. Поэтому можно выполнить User.instance_methods, чтобы получить массив методов экземпляра User.

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