Frage

Was macht class << self in Ruby tun?

War es hilfreich?

Lösung

Zuerst die class << foo Syntax öffnet sich foo's Singleton -Klasse (Eigenclass). Auf diese Weise können Sie das Verhalten von Methoden spezialisiert, die dieses spezifische Objekt aufrufen.

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

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

Nun, um die Frage zu beantworten: class << self eröffnet selfDie Singleton -Klasse, damit Methoden für den Strom neu definiert werden können self Objekt (das in einer Klasse oder einem Modulkörper ist die Klasse oder das Modul selbst). Normalerweise wird dies verwendet, um Klassen/Modul ("statische") Methoden zu definieren:

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

String.value_of 42   # => "42"

Dies kann auch als Abkürzung geschrieben werden:

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

Oder noch kürzer:

def String.value_of obj
  obj.to_s
end

Wenn Sie in einer Funktionsdefinition in einer Funktionsdefinition sind, self Bezieht sich auf das Objekt, mit dem die Funktion aufgerufen wird. In diesem Fall, class << self öffnet die Singleton -Klasse für dieses Objekt; Eine Verwendung davon besteht darin, die Staatsmaschine eines armen Mannes zu implementieren:

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

Also im obigen Beispiel jede Instanz von StateMachineExample hat process_hook Alias process_state_1, aber beachten Sie, wie es in letzterem neu definieren kann process_hook (zum self nur, nicht andere beeinflussen StateMachineExample Instanzen) zu process_state_2. Jedes Mal, wenn ein Anrufer das anruft process Methode (die die neu definierbare Aufrufe nennt process_hook), Das Verhalten ändert sich je nach Zustand, in dem es sich befindet.

Andere Tipps

Ich fand eine super einfache Erklärung zu class << self , Eigenclass und unterschiedliche Art von methods in diesem Blog.

In Ruby gibt es drei Arten von Methoden, die auf eine Klasse angewendet werden können:

  1. Instanzmethoden
  2. Singleton -Methoden
  3. Klassenmethoden

Instanzmethoden und Klassenmethoden ähneln in anderen Programmiersprachen fast ihrem Homonymous.

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

Eine andere Möglichkeit, auf einen zuzugreifen Eigenclass(einschließlich Singleton -Methoden) ist mit der folgenden Syntax (class <<):

foo = Foo.new

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

Jetzt können Sie eine Singleton -Methode für definieren self Welches ist die Klasse Foo selbst in diesem Zusammenhang:

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

In der Regel sind Instanzmethoden globale Methoden. Das bedeutet, dass sie in allen Fällen der Klasse verfügbar sind, in denen sie definiert wurden. Im Gegensatz dazu wird eine Singleton -Methode auf einem einzelnen Objekt implementiert.

Ruby speichert Methoden in Klassen und alle Methoden müssen mit einer Klasse in Verbindung gebracht werden. Das Objekt, auf dem eine Singleton -Methode definiert ist, ist keine Klasse (es ist eine Instanz einer Klasse). Wenn nur Klassen Methoden speichern können, wie kann ein Objekt eine Singleton -Methode speichern? Wenn eine Singleton -Methode erstellt wird, erstellt Ruby automatisch eine anonyme Klasse, um diese Methode zu speichern. Diese anonymen Klassen werden als Metaklasse bezeichnet, auch als Singleton -Klassen oder Eigenklassen bezeichnet. Die Singleton -Methode ist mit der Metaklas verbunden, die wiederum dem Objekt zugeordnet ist, auf dem die Singleton -Methode definiert wurde.

Wenn mehrere Singleton -Methoden in einem einzelnen Objekt definiert sind, werden sie alle in derselben Metaklas gespeichert.

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'…

Im obigen Beispiel ändert Klasse << Z1 das aktuelle Selbst, um auf die Metaklasse des Z1 -Objekts zu verweisen. Dann definiert es die Say_hello -Methode innerhalb der Metaklasse.

Klassen sind auch Objekte (Instanzen der integrierten Klasse namens Klasse). Klassenmethoden sind nichts anderes als Singleton -Methoden, die einem Klassenobjekt zugeordnet sind.

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

Alle Objekte können Metaklasse haben. Das bedeutet, dass Klassen auch Metaklasse haben können. Im obigen Beispiel verändert die Klasse << Selbst das Selbst, so dass es auf die Metaklasse der Zabuton -Klasse weist. Wenn eine Methode ohne expliziten Empfänger definiert wird (die Klasse/das Objekt, auf der die Methode definiert wird), ist sie implizit im aktuellen Bereich definiert, dh im aktuellen Wert des Selbst. Daher wird die Stuff -Methode in der Metaklasse der Zabuton -Klasse definiert. Das obige Beispiel ist nur eine weitere Möglichkeit, eine Klassenmethode zu definieren. IMHO, es ist besser, das Def self zu verwenden. Das obige Beispiel wurde enthalten, damit wir verstehen, was passiert, wenn wir auf die Klasse << Selbstsyntax stoßen.

Zusätzliche Informationen finden Sie unter Dieser Beitrag über Ruby -Klassen.

Welche Klasse << Ding tut:

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

es macht self == thing.singleton_class im Kontext seines Blocks.


Was ist Ding.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 Objekt erbt seine #methods von seinem #singleton_class.instance_methods und dann von seinem #class.instance_methods.
Hier gaben wir hi's Singleton -Klasse Instanzmethode :a. Es hätte mit erledigt werden können mit Klasse << hi stattdessen.
hi's #singleton_class hat alle Instanzmethoden hi's #class hat und möglicherweise einige mehr (:a hier).

Instanzmethoden von Dingen #class und #singleton_class kann direkt auf Dinge angewendet werden. Wenn Ruby etwas sieht.a, sucht es zuerst nach: eine Methode Definition in Thing.singleton_class.instance_methods und dann in Thing.class.instance_methods


Übrigens - sie nennen Objekte Singleton -Klasse == Metaklas == Eigenclass.

А Singleton -Methode ist eine Methode, die nur für ein einzelnes Objekt definiert ist.

Beispiel:

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

Singletons Methoden der Someklasse

Prüfung


Singletons Methoden von test_obj

test_2

test_3

Wenn Sie C -Erweiterungen für Ihre Ruby -Projekte schreiben, gibt es wirklich nur eine Möglichkeit, eine Modulmethode zu definieren.

rb_define_singleton_method

Ich weiß, dass dieses Selbstgeschäft nur alle möglichen anderen Fragen eröffnet, sodass Sie es besser machen können, indem Sie jeden Teil durchsuchen.

Objekte zuerst.

foo = Object.new

Kann ich eine Methode für Foo erstellen?

Sicher

def foo.hello
 'hello'
end

Was mache ich damit?

foo.hello
 ==>"hello"

Nur ein weiteres Objekt.

foo.methods

Sie erhalten alle Objektmethoden sowie Ihre neue.

def foo.self
 self
end

foo.self

Nur das Foo -Objekt.

Versuchen Sie zu sehen, was passiert, wenn Sie Foo aus anderen Objekten wie Klasse und Modul machen. Die Beispiele aller Antworten sind schön zu spielen, aber Sie müssen mit verschiedenen Ideen oder Konzepten arbeiten, um wirklich zu verstehen, was mit der Art und Weise geschrieben wird, wie der Code geschrieben wird. Jetzt haben Sie also viele Begriffe zu sehen.

Singleton, Klasse, Modul, Selbst, Objekt und Eigenklass wurden angesprochen, aber Ruby nennt Objektmodelle nicht so. Es ist eher wie Metaclass. Richard oder __why zeigt Ihnen hier die Idee.http://viewsourcecode.org/why/hacking/seeingmetaclassesclearly.htmlUnd wenn Sie sich wegblasen, versuchen Sie, das Ruby -Objektmodell auf der Suche nachzuschlagen. Zwei Videos, die ich auf YouTube kenne, sind Dave Thomas und Peter Cooper. Sie versuchen auch, dieses Konzept zu erklären. Es dauerte lange, bis Dave es bekam, also mach dir keine Sorgen. Ich arbeite auch immer noch daran. Warum wäre ich sonst hier? Vielen Dank für Ihre Frage. Schauen Sie sich auch die Standardbibliothek an. Es hat ein Singleton -Modul wie eine FYI.

Das ist ziemlich gut.https://www.youtube.com/watch?v=i4uiywa8efk

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top