2014-12-25 8 views
5

Non ho abbastanza dettagli sul modello di oggetti Ruby. Innanzitutto, TUTTO è in Ruby un'istanza di Class? Questi tutti producono vero:Perché TUTTO è un'istanza di Class in Ruby?

p Object.instance_of?(Class) 
p Class.instance_of?(Class) 
p Module.instance_of?(Class) 
p BasicObject.instance_of?(Class) 
class Hello; end 
p Hello.instance_of?(Class) 

non riesco quasi mai come è possibile, se Object è una superclasse di Class, come può essere sia una superclasse di Class e un'istanza di esso, allo stesso tempo (la maggior parte dei diagrammi sul modello di oggetti Ruby indica chiaramente questa gerarchia)? Che consente una certa follia come questa:

p BasicObject.is_a?(Object) #=> true 

dove BasicObject.class è Class e Class.is_a?(Object).

A proposito, utilizzando Ruby 2.0.

risposta

11

Per prima cosa, TUTTO è in Ruby un'istanza di Class?

No, non tutto è un'istanza di Class. Solo le classi sono istanze di Class.

Ci sono molte cose che non sono istanze di Class: le stringhe, ad esempio, sono istanze di String, non Class. Gli array sono istanze di Array, interi sono casi di Integer, carri sono casi di Float, true è un'istanza di TrueClass, false è un'istanza di FalseClass, nil è un'istanza di NilClass, e così via.

Ogni classe è un'istanza di Class, proprio come ogni stringa è un'istanza di String.

se Object è una superclasse di Class, come può essere sia una superclasse di Class e un'istanza di esso, allo stesso tempo (la maggior parte dei diagrammi sulla Rubino Object Model indicare chiaramente questa gerarchia)?

Magico.

Proprio come nella maggior parte degli altri linguaggi, esistono alcune entità principali che si presume esistano. Cadono dal cielo, si materializzano dal nulla, appaiono magicamente.

In Ruby, alcune di quelle cose magiche sono:

  • Object non hai superclasse, ma non si può definire una classe senza superclasse, la superclasse diretta implicito è sempre Object. [Nota: potrebbero esserci superclassi definiti dall'implementazione di Object, ma alla fine ce ne sarà uno che non ha una superclasse.]
  • Object è un'istanza di Class, che è una sottoclasse di Object (il che significa che indirettamente Object è un'istanza di Object stesso)
  • Class è una sottoclasse di Module, che è un esempio di Class
  • Class è un'istanza di Class

Nessuna di queste cose può essere spiegata in Ruby.

BasicObject, Object, Module e Class tutti devono provoca l'esistenza contemporaneamente perché hanno dipendenze circolari.

Solo perché questa relazione non può essere espressa in codice Ruby, non significa che la specifica del linguaggio Ruby non possa dire che deve essere così. Spetta al implementatore trovare un modo per farlo. Dopotutto, l'implementazione di Ruby ha un livello di accesso agli oggetti che voi come programmatori non avete.

Ad esempio, l'applicazione rubino potrebbe creare prima BasicObject, modificando sia il suo puntatore superclass e la sua class puntatore null.

Poi, crea Object, impostando il suo puntatore superclass per BasicObject e la sua class puntatore a null.

Avanti, crea Module, impostando il suo puntatore superclass-Object e la sua class puntatore a null.

Infine, crea Class, impostando il suo puntatore superclass-Module e la sua class puntatore a null.

Ora, siamo in grado di sovrascrivere BasicObject 's, Object' s, Module 's, e Class' class puntatore s per puntare a Class, e abbiamo finito.

Questo è facile da eseguire dall'esterno del sistema, sembra solo strano dall'interno.

2

Si dovrebbe notare che:

p BasicObject.instance_of?(BasicObject) 

stampe false.

Cioè, l'espressione BasicObject non è un'istanza di BasicObject, è un esempio di qualcos'altro, cioè, uno scopo Class, che rappresenta un oggetto che contiene (per esempio) i metodi della classe, come new.

Ad esempio:

p (BasicObject.new()).instance_of?(BasicObject) 

stampe true, e

p (BasicObject.new()).instance_of?(Class) 

stampe false.

0

Tutti i tuoi esempi erano per classi di definizione. Le classi sono anche oggetti. Ma quello che non hai fatto era un'occhiata a un'istanza di una classe:

p Object.new.class 
p Hello.new.class 

classi definiscono la forma di un oggetto, e per definizione, una classe è una classe. Ma quando installi classe in un oggetto, l'oggetto è il nuovo tipo. Ma si può ancora vedere che la classe dell'oggetto è di per sé Classe:

p Hello.new.class.class 
+0

La tua ultima frase dovrebbe probabilmente essere "... che la classe di classe dell'oggetto è di per sé' class'" o "... che classe dell'oggetto è essa stessa una (n istanza di) 'Classe'" –

Problemi correlati