Question

Je suis un Rubis starter.J'ai trouvé ces deux sont assez similaires (en sortie), mais je ne pouvais pas comprendre la différence dans le contexte ci-dessous.Par exemple, j'ai une classe

class Say
  def self.hello
    puts "hello"
  end
end

et peut être étendu comme ceci

class << Say
  def hi
    puts "hi"
  end
end

et aussi comme ça

Say.class_eval do
  def self.bye
    puts "bye"
  end
end

Quand dois-je utiliser << et quand class_eval?

Était-ce utile?

La solution

class_eval n'a pas vraiment rien avoir à faire avec class << className.

A.class_eval do
   ...
end

est équivalent à

class A
  ...
end

avec quelques différences.class_eval utilise un bloc (ou une chaîne de caractères, mais en ignorant que pour le moment), ce qui signifie qu'il se ferme sur le contenant de la portée lexicale.En d'autres termes, vous pouvez utiliser des variables locales à partir de l'environnement de la portée.La commune de la classe bloc introduit un tout nouveau champ d'application.De même, vous pouvez créer le bloc et de le transmettre à beaucoup de différents class_eval, et le corps du bloc sera exécuté dans le contexte de la classe que vous appelez class_eval sur.

class << className ouvre la classe singleton de className, vous permettant de définir les méthodes de la classe.

class << A
  def foo
    ...
  end
end

Est le même que

def A.foo
  ...
end

Notez qu'ils sont oly les méthodes de la classe si l'Un se trouve être une classe de (presque) tous les objets en ruby ont singleton classes et vous pouvez définir des méthodes à l'aide de l'une de ces deux syntaxes.L'avantage de class << obj est principalement si vous êtes à la définition de nombreux singleton méthodes en une seule fois.

Autres conseils

Comme déjà dit, class_eval n'a vraiment pas grand chose à voir avec

class <<self

même s'ils semblent faire la même chose dans votre exemple (bien que l'effet soit similaire, il ne fait pas la même chose, il y a des différences subtiles).

Voici un autre exemple où l'utilisation du deuxième formulaire est beaucoup plus claire:

class A

end


a = A.new
b = A.new

class <<b
  def say_hi
    puts "Hi !"
  end
end


b.say_hi # will print "Hi !"
a.say_hi # will raise an undefined method

a et b sont tous deux des objets de la même classe A mais nous avons ajouté une méthode à la métaclasse de b donc la méthode say_hi n'est disponible que pour l'objet b.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top