class

Co robi class << selfW Ruby?

Author: Arsen Khachaturyan, 2010-03-24

6 answers

Po pierwsze, składnia class << foo otwiera foo klasę singleton (eigenclass). Pozwala to na wyspecjalizowanie zachowania metod wywołanych na danym obiekcie.

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

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

Teraz, aby odpowiedzieć na pytanie: class << self otwiera klasę singleton self, tak aby metody mogły być przedefiniowane dla bieżącego obiektu self (który wewnątrz klasy lub ciała modułu jest klasą lub modułem ). Zazwyczaj jest to używane do definiowania metod klasy / modułu ("statycznych"):

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

String.value_of 42   # => "42"

To może należy również zapisać jako skrót:

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

Lub jeszcze krócej:

def String.value_of obj
  obj.to_s
end

Gdy wewnątrz definicji funkcji, self odnosi się do obiektu, z którym wywołana jest funkcja. W tym przypadku class << self otwiera klasę singleton dla tego obiektu; jednym z jej zastosowań jest zaimplementowanie maszyny stanowej biednego człowieka:

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

W powyższym przykładzie każda instancja StateMachineExample ma process_hook aliasowane do process_state_1, ale zauważ, jak w tym ostatnim może przedefiniować process_hook (tylko dla self, nie wpływając inne instancje StateMachineExample) do process_state_2. Tak więc, za każdym razem, gdy wywołujący wywołuje metodę process (która wywołuje ponownie zdefiniowaną process_hook), zachowanie zmienia się w zależności od tego, w jakim stanie się znajduje.

 941
Author: Chris Jester-Young,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-06 17:15:22

Znalazłem super proste wyjaśnienie o class << self , Eigenclass i różnego rodzaju metod.

W Rubim istnieją trzy rodzaje metod, które można zastosować do klasy:

  1. metody instancji
  2. metody Singletona
  3. metody klas

Metody instancji i metody klas są prawie podobne do ich homonimicznych w innych językach programowania.

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

Innym sposobem dostępu do Eigenclass (który obejmuje metody Singletona) jest następująca składnia (class <<):

foo = Foo.new

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

Teraz możesz zdefiniować metodę Singletona dla self, która jest klasą Foo w tym kontekście:

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
 42
Author: Saman Mohamadi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-09 16:34:24

Zazwyczaj metody instancji są metodami globalnymi. Oznacza to, że są one dostępne we wszystkich instancjach klasy, na której zostały zdefiniowane. Natomiast metoda singleton jest zaimplementowana na jednym obiekcie.

Ruby przechowuje metody w klasach i wszystkie metody muszą być powiązane z klasą. Obiekt, na którym zdefiniowana jest metoda singleton, nie jest klasą (jest instancją klasy). Jeśli tylko klasy mogą przechowywać metody, w jaki sposób obiekt może przechowywać metodę singleton? Gdy metoda Singletona jest tworzony, Ruby automatycznie tworzy anonimową klasę do przechowywania tej metody. Te anonimowe klasy nazywane są metaklasami, znane również jako klasy Singletona lub eigenklasy. Metoda singleton jest powiązana z metaklasą, która z kolei jest powiązana z obiektem, na którym została zdefiniowana metoda singleton.

Jeśli w obrębie jednego obiektu zdefiniowanych jest wiele metod Singletona, wszystkie są przechowywane w tej samej metaklasie.

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

W powyższym przykładzie Klasa

Klasy są również obiektami (instancjami wbudowanej klasy o nazwie Class). Metody klasy to nic innego jak metody Singletona związane z obiektem klasy.

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

Wszystkie obiekty mogą mieć metaklasy. Oznacza to, że klasy mogą mieć również metaklasy. W powyższym przykładzie, Klasa

Dodatkowe informacje można znaleźć w ten post o klasach Ruby.

 25
Author: BrunoFacca,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-20 12:08:16

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

[sprawia, że self == thing.singleton_class w kontekście jego bloku] .


Czym jest rzecz.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 obiekt dziedziczy swój #methods z jego #singleton_class.instance_methods, a następnie z jego #class.instance_methods.
Tutaj podaliśmy metodę instancji hi klasy singleton :a. Można było to zrobić za pomocą klasy .
hi's #singleton_class posiada wszystkie instancje metod hi'S #class has, i ewentualnie kilka innych (:a tutaj).

[metody instancji rzeczy #class oraz #singleton_class może być stosowany bezpośrednio do rzeczy. kiedy ruby coś zobaczy.a, najpierw szuka: definicji metody w rzeczy.singleton_class.instance_methods, a następnie w rzeczy.klasy.instance_methods]


Przy okazji-nazywają obiekt klasą singleton == metaklass == eigenclass .

 17
Author: lakesare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

A metoda Singletona jest metodą zdefiniowaną tylko dla pojedynczego obiektu.

Przykład:

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

Singleton ' s methods of SomeClass

badanie


Singleton ' s methods of test_obj

test_2

test_3

 3
Author: artamonovdev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-15 18:50:59

W rzeczywistości, jeśli piszesz jakieś rozszerzenia C dla swoich projektów Ruby, jest tylko jeden sposób na zdefiniowanie metody modułu.

rb_define_singleton_method

Wiem, że ten własny biznes otwiera wszystkie rodzaje innych pytań, więc możesz zrobić lepiej, przeszukując każdą część.

Najpierw obiekty.

foo = Object.new

Czy Mogę zrobić metodę na foo?

Jasne

def foo.hello
 'hello'
end
Co mam z tym zrobić?
foo.hello
 ==>"hello"
Kolejny obiekt.
foo.methods

Otrzymujesz wszystkie metody obiektowe plus Twój nowy jeden.

def foo.self
 self
end

foo.self

Tylko obiekt foo.

Spróbuj zobaczyć, co się stanie, jeśli zrobisz foo z innych obiektów, takich jak klasa i moduł. Przykłady ze wszystkich odpowiedzi są przyjemne do zabawy, ale trzeba pracować z różnymi pomysłami lub koncepcjami, aby naprawdę zrozumieć, co się dzieje ze sposobem pisania kodu. Więc teraz masz wiele warunków do obejrzenia.

Singleton, Klasa, Moduł, self, Obiekt, i eigenclass został podniesiony, ale Ruby nie nazywa modeli obiektowych w ten sposób. On raczej Metaclass. Richard or _ _ why pokazuje ci pomysł tutaj. http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html A jeśli to cię rozwali, spróbuj poszukać Ruby Object Model w wyszukiwarce. Dwa filmy, które znam na YouTube to Dave Thomas i Peter Cooper. Próbują też wyjaśnić tę koncepcję. Zajęło Dave ' owi dużo czasu, żeby go zdobyć, więc nie martw się. Też nad tym pracuję. A po co miałbym tu być? Dzięki za pytanie. Przyjrzyj się również standardowi biblioteka. Ma moduł Singleton tak jak FYI. To jest całkiem niezłe. https://www.youtube.com/watch?v=i4uiyWA8eFk
 1
Author: Douglas G. Allen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-08 14:34:27