Question

class << self
attr_accessor :n, :totalX, :totalY
end

La syntaxe est utilisée ci-dessus pour la définition des variables d'instance de classe. Mais quand je pense à ce que la syntaxe implique, il ne fait pas de sens pour moi, alors je me demande si ce type de syntaxe est utilisée pour tous les autres types de définitions. Mon point de confusion ici est la suivante:

class << self

L'opérateur append signifie normalement « ajouter ce qui est sur le droit à l'objet à gauche ». Mais dans le contexte de ce bloc, comment cela ajouter jusqu'à « mettre le contenu de ce bloc dans la définition de l'instance de la classe plutôt que l'instance »?

Pour la même raison, je suis confus quant à la raison pour laquelle dans une classe de contexte << auto peut définir des variables d'instance de classe alors que dans une autre, il semble créer des variables de classe comme ici:

class Point
  # Instance methods go here
  class << self
    # Class methods go here
  end
end
Était-ce utile?

La solution

Ruby vous pouvez rouvrir les classes et ajouter des méthodes existantes. Autrement dit, vous pouvez dire:

class Foo
  def bob
    return "hello from bob"
  end
end

ces méthodes sont stockés quelque part dans un dictionnaire interne (peut-être une variable d'instance) de la Foo classe (qui est juste une instance de la Class classe et donc a variables d'instance)

Mais la chose est surprenante, que vous pouvez également ajouter des méthodes instances d'objets existants

foo = Foo.new
foo2 = Foo.new

def foo.fred
  return "I am fred"
end


foo.fred  #=> "I am fred"
foo2.fred #=> NoMethodError

Où est cette méthode réellement stocké ?

Turns out Ruby crée une nouvelle classe dans les coulisses (parfois appelé class singleton , métaclasse ou eigenclass ) qui est insérée dans l'héritage heirarchy entre la Foo classe et son instance.

Ainsi, la relation d'héritage ressemble à ça:

foo < (eigenclass of foo) < Foo < Class

(si vous dites foo.superclass vous ne verrez pas la classe singleton)

la class << X-syntaxe est un moyen d'arriver à cette classe spéciale, afin que vous puissiez le manipuler directement. Les blocs de code suivants sont exactement équivalentes:

def foo.bar
  return "xy"
end

# is exactly the same as

class << foo
  def bar
    return "xy"
  end
end

Ainsi, la similitude entre class Foo < Bar et class << Foo est pas par hasard, il y a l'héritage se passe dans les deux.

Pensez à class << X comme "ouvrir la métaclasse de X"

La chose à retenir est que Ruby dans les classes elles-mêmes ne sont que des objets. (Les instances de la Class de classe), donc si vous dites:

class Foo
  class << self
    def k
      return "x"
    end
  end
end

(self est lié à Foo dans ce bloc de code) de manière k est une méthode instance des eigenclass de Foo, ce qui en fait une méthode de classe pour Foo

tout cela est plus clairement expliqué dans le (la version web ne contient pas les diagrammes, malheureusement) et _whys en voyant métaclasses Il est clair que

Autres conseils

Pensez à la classe comme contenant un dictionnaire des membres, y compris tous les accesseurs et les variables d'instance. Lorsque vous dites la classe à « ajouter » à « lui-même », vous dites « ajoutez-les au dictionnaire des membres de la classe. »

Je vais accorder la notation est un peu louche, cependant.

il est en fait déroutant de penser en termes d'un opérateur « ajouter ». une meilleure façon de regarder est que, tout comme class Foo ouvre la classe Foo, qui est, il définit « soi » à l'objet de classe Foo, créant si nécessaire, si class << self ouvre les eigenclass du courant objet « auto ». noter qu'il ne se limite pas à l'auto -. pour une barre d'objets, vous pouvez dire la classe << bar pour ouvrir les eigenclass de cet objet

class A
  def hello
    print "hello world"
  end
end

a = A.new
b = A.new

class << a
  def goodbye
    print "goodbye cruel world"
  end
end

a.hello
b.hello
a.goodbye
b.goodbye
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top