Question classe << self idiome dans Ruby


Qu'est-ce que class << self faire en Ruby?


739
2018-03-24 03:02


origine


Réponses:


Premièrement la class << foo la syntaxe s'ouvre fooLa classe singleton (eigenclass). Cela vous permet de spécialiser le comportement des méthodes appelées sur cet objet spécifique.

a = 'foo'
class << a
  def inspect
    '"bar"'
  end
end
a.inspect   # => "bar"

a = 'foo'   # new object, new singleton class
a.inspect   # => "foo"

Maintenant, pour répondre à la question: class << self ouvre selfla classe singleton, de sorte que les méthodes peuvent être redéfinies pour le courant self objet (qui dans une classe ou un corps de module est la classe ou le module se). Habituellement, ceci est utilisé pour définir les méthodes class / module ("static"):

class String
  class << self
    def value_of obj
      obj.to_s
    end
  end
end

String.value_of 42   # => "42"

Cela peut aussi être écrit comme un raccourci:

class String
  def self.value_of obj
    obj.to_s
  end
end

Ou même plus court:

def String.value_of obj
  obj.to_s
end

À l'intérieur d'une définition de fonction, self fait référence à l'objet avec lequel la fonction est appelée. Dans ce cas, class << self ouvre la classe singleton pour cet objet; une utilisation de cela est de mettre en œuvre la machine d'état d'un pauvre:

class StateMachineExample
  def process obj
    process_hook obj
  end

private
  def process_state_1 obj
    # ...
    class << self
      alias process_hook process_state_2
    end
  end

  def process_state_2 obj
    # ...
    class << self
      alias process_hook process_state_1
    end
  end

  # Set up initial state
  alias process_hook process_state_1
end

Ainsi, dans l'exemple ci-dessus, chaque instance de StateMachineExample a process_hook aliasé à process_state_1, mais notez comment dans ce dernier, il peut redéfinir process_hook (pour self seulement, n'affectant pas les autres StateMachineExample instances) à process_state_2. Ainsi, chaque fois qu'un appelant appelle le process méthode (qui appelle le redéfinissable process_hook), le comportement change en fonction de l'état dans lequel il se trouve.


789
2018-03-24 03:05



J'ai trouvé une explication super simple à propos de class << self , Eigenclass et différent type de methods dans ce Blog.

Dans Ruby, il existe trois types de méthodes qui peuvent être appliquées à une classe:

  1. Méthodes d'instance
  2. Méthodes singleton
  3. Méthodes de classe

Les méthodes d'instance et les méthodes de classe sont presque similaires à leur homonyme dans d'autres langages de programmation.

class Foo  
  def an_instance_method  
    puts "I am an instance method"  
  end  
  def self.a_class_method  
    puts "I am a class method"  
  end  
end

foo = Foo.new

def foo.a_singleton_method
  puts "I am a singletone method"
end

Une autre façon d'accéder à un Eigenclass(qui inclut des méthodes singleton) est avec la syntaxe suivante (class <<):

foo = Foo.new

class << foo
  def a_singleton_method
    puts "I am a singleton method"
  end
end

maintenant vous pouvez définir une méthode singleton pour self qui est la classe Foo dans ce contexte:

class Foo
  class << self
    def a_singleton_and_class_method
      puts "I am a singleton method for self and a class method for Foo"
    end
  end
end

24
2018-01-29 11:37



Quelle classe << chose fait:

class Hi
  self #=> Hi
  class << self #same as 'class << Hi'
    self #=> #<Class:Hi>
    self == Hi.singleton_class #=> true
  end
end

[cela fait  self == thing.singleton_class  dans le contexte de son bloc].


Qu'est-ce que thing.singleton_class?

hi = String.new
def hi.a
end

hi.class.instance_methods.include? :a #=> false
hi.singleton_class.instance_methods.include? :a #=> true

hi objet hérite de son #methods de son #singleton_class.instance_methods puis de son #class.instance_methods.
Ici nous avons donné hide classe singleton méthode d'instance :a. Cela aurait pu être fait avec classe << salut au lieu.
hide #singleton_class a toutes les méthodes d'instance hide #class a, et peut-être un peu plus (:a ici).

[méthodes d'instance de chose  #class  et  #singleton_class  peut être appliqué directement à la chose. quand ruby ​​voit thing.a, il cherche d'abord: une définition de méthode dans thing.singleton_class.instance_methods et ensuite dans thing.class.instance_methods]


En passant - ils appellent l'objet classe singleton == métaclasse == classe propre.


12
2017-11-12 14:03



Généralement, les méthodes d'instance sont des méthodes globales. Cela signifie qu'ils sont disponibles dans toutes les instances de la classe sur laquelle ils ont été définis. En revanche, une méthode singleton est implémentée sur un seul objet.

Ruby stocke les méthodes dans les classes et toutes les méthodes doivent être associées à une classe. L'objet sur lequel une méthode singleton est définie n'est pas une classe (c'est une instance d'une classe). Si seules les classes peuvent stocker des méthodes, comment un objet peut-il stocker une méthode singleton? Lorsqu'une méthode singleton est créée, Ruby crée automatiquement une classe anonyme pour stocker cette méthode. Ces classes anonymes sont appelées métaclasses, également appelées classes singleton ou classes propres. La méthode singleton est associée à la métaclasse qui, à son tour, est associée à l'objet sur lequel la méthode singleton a été définie.

Si plusieurs méthodes singleton sont définies dans un même objet, elles sont toutes stockées dans la même métaclasse.

class Zen
end

z1 = Zen.new
z2 = Zen.new

class << z1
  def say_hello
    puts "Hello!"
  end
end

z1.say_hello    # Output: Hello!
z2.say_hello    # Output: NoMethodError: undefined method `say_hello'…

Dans l'exemple ci-dessus, la classe << z1 change le self courant pour pointer vers la métaclasse de l'objet z1; Ensuite, il définit la méthode say_hello dans la métaclasse.

Les classes sont également des objets (instances de la classe intégrée appelée Class). Les méthodes de classe ne sont rien de plus que des méthodes singleton associées à un objet de classe.

class Zabuton
  class << self
    def stuff
      puts "Stuffing zabuton…"
    end
  end
end

Tous les objets peuvent avoir des métaclasses. Cela signifie que les classes peuvent aussi avoir des métaclasses. Dans l'exemple ci-dessus, la classe << self modifie self de sorte qu'elle pointe vers la métaclasse de la classe Zabuton. Lorsqu'une méthode est définie sans récepteur explicite (la classe / objet sur laquelle la méthode sera définie), elle est implicitement définie dans la portée actuelle, c'est-à-dire la valeur actuelle de self. Par conséquent, la méthode stuff est définie dans la métaclasse de la classe Zabuton. L'exemple ci-dessus est juste une autre façon de définir une méthode de classe. À mon humble avis, il est préférable d'utiliser la syntaxe def self.my_new_clas_method pour définir les méthodes de classe, car il rend le code plus facile à comprendre. L'exemple ci-dessus a été inclus afin que nous comprenions ce qui se passe lorsque nous rencontrons la syntaxe self de la classe <<.

Des informations supplémentaires peuvent être trouvées sur ce post sur Ruby Classes.


11
2018-06-26 18:17



А méthode singleton est une méthode définie uniquement pour un seul objet.

Exemple:

class SomeClass
  class << self
    def test
    end
  end
end

test_obj = SomeClass.new

def test_obj.test_2
end

class << test_obj
  def test_3
  end
end

puts "Singleton's methods of SomeClass"
puts SomeClass.singleton_methods
puts '------------------------------------------'
puts "Singleton's methods of test_obj"
puts test_obj.singleton_methods

Les méthodes de Singleton de Singleton

tester


Les méthodes de Singleton de test_obj

test_2

test_3


3
2017-09-15 18:50



En fait, si vous écrivez des extensions C pour vos projets Ruby, il n'y a vraiment qu'une seule façon de définir une méthode Module.

rb_define_singleton_method

Je sais que cette auto-entreprise ouvre toutes sortes d'autres questions afin que vous puissiez faire mieux en cherchant chaque partie.

Objets en premier.

foo = Object.new

Puis-je faire une méthode pour foo?

Sûr

def foo.hello
 'hello'
end

Qu'est-ce que je fais avec?

foo.hello
 ==>"hello"

Juste un autre objet.

foo.methods

Vous obtenez toutes les méthodes d'objet plus votre nouveau.

def foo.self
 self
end

foo.self

Juste l'objet foo.

Essayez de voir ce qui se passe si vous faites foo à partir d'autres objets comme la classe et le module. Les exemples de toutes les réponses sont agréables à jouer, mais vous devez travailler avec différentes idées ou concepts pour vraiment comprendre ce qui se passe avec la façon dont le code est écrit. Alors maintenant vous avez beaucoup de termes à regarder.

Singleton, Classe, Module, soi, Objet, et Eigenclass a été présenté mais Ruby ne nomme pas Object Models de cette façon. C'est plus comme Metaclass. Richard ou __why vous montre l'idée ici. http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html Et si le coup vous bloque alors essayez de chercher Ruby Object Model dans la recherche. Deux vidéos que je connais sur YouTube sont Dave Thomas et Peter Cooper. Ils essaient d'expliquer ce concept aussi. Il a fallu longtemps à Dave pour l'avoir, alors ne vous inquiétez pas. Je travaille toujours dessus aussi. Sinon, pourquoi serais-je ici? Merci pour votre question Jetez également un coup d'oeil à la bibliothèque standard. Il a un module de Singleton juste comme un FYI.

C'est plutôt bien. https://www.youtube.com/watch?v=i4uiyWA8eFk


1
2018-05-08 13:29