4 votes

Comment Object connaît-il la méthode const_get ?

Je lisais une autre question avec un réponse qui mentionne l'utilisation de la Module#const_get pour trouver une classe dans un module. Par exemple :

module M
  class C
  end
end

p M.const_get 'C'
#=> M::C

J'étais curieux de savoir const_get j'ai donc utilisé la méthode ri et j'ai trouvé :

ri Module#const_get
...
This method will recursively look up constant names if a namespaced
class name is provided.  For example:

  module Foo; class Bar; end end
  Object.const_get 'Foo::Bar'
...

Il semble que Object::const_get est une méthode singleton. L'utiliser dans notre contexte fonctionne :

module M
  class C
  end
end

p Object.const_get 'M::C'
#=> M::C

Mais il n'y a rien de documenté sur cette méthode singleton :

ri Object::const_get
Nothing known about Object::const_get
ri Object.const_get
Nothing known about Object.const_get

Cela m'a troublé car je connais un Module est un Object mais un Object n'est pas un Module :

Module.ancestors
#=> [Module, Object, Kernel, BasicObject]
Object.ancestors
#=> [Object, Kernel, BasicObject]

Sauf qu'ensuite j'ai utilisé le Object#is_a? méthode d'instance pour vérifier et j'ai vu que j'avais tort à ce sujet :

Module.is_a? Object
#=> true
Object.is_a? Module
#=> true

Ce qui a commencé comme une innocente ri m'a conduit à être confus à propos de l'ensemble du modèle objet de Ruby.

  • Pourquoi est-ce que Object.is_a? Module #=> true si Module n'est pas dans Object de la chaîne d'ancêtres de l'entreprise ?
  • Comment Object savoir sur le const_get méthode ?

6voto

tadman Points 70178

Il s'agit d'un artefact de la séparation mal comprise entre la classe d'un objet et son classe unique une sorte de classe fantôme que chaque classe utilise pour ce genre de choses.

Vous pouvez y accéder facilement en Ruby 2.5+ avec la fonction singleton_class método:

Object.singleton_class.ancestors
# => [#<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]

Module fait son apparition ici, et c'est ainsi que ces méthodes sont intégrées et peuvent être appelées par l'intermédiaire de Object .

L'objet lui-même a une chaîne d'héritage relativement ennuyeuse :

Object.ancestors
#=> [Object, Kernel, BasicObject]

Chaque objet dans Ruby a une classe, même Class est un Object qui est également associé à un Class .

1voto

mu is too short Points 205090

Je pense que votre confusion vient du fait que vous regardez Object de deux directions à la fois :

  1. Object est une classe donc Object.ancestors peut être utilisé pour examiner la hiérarchie de l'héritage. Cela vous indique que Object < Kernel est vrai et Object < Module est fausse.
  2. Les classes en Ruby sont également des objets, plus précisément des instances de la classe Class classe. Cela vous indique que Object.is_a? Class y Object.is_a? Module de la même manière que 'pancakes'.is_a? String . Et que Object.const_get est un appel de méthode de la même manière que 'pancakes'.upcase est un appel de méthode.

Vous pouvez penser à some_obj.is_a? SomeClass comme une façon plus courte de dire some_obj.class.ancestors.include? SomeClass .

Répondre à vos questions spécifiques :

  1. Pourquoi est-ce que Object.is_a? Module #=> true si Module n'est pas dans Object La chaîne d'ancêtres de l'enfant ?

    Parce que is_a? y ancestors regardent des choses différentes.

  2. Comment Object savoir sur le const_get méthode ?

    Parce que Object est une instance de la Class et Class comprend Module dans ses ancêtres. De la même manière que 'pancakes' est une instance de la String qui a Kernel dans ses ancêtres, donc 'pancakes' a un object_id méthode.

0voto

Sagar Pandya Points 7821

Object.is_a? Module #=> true

is_a? se demande si Object est une instance (ou une instance spécialisée) de Module . Class est une sous-classe de Module donc toutes les instances de Class sont vraiment des instances spécialisées de Module . Puisque Object est une instance de Class il s'ensuit que Object est également une instance de Module .

Module#const_get

const_get est une méthode d'instance définie dans le cadre du Module classe. Puisque Object est une instance de Module (pour les raisons évoquées ci-dessus), elle a accès à Module#const_get .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X