Что делает class << self
в Ruby ?
ruby
metaclass
eigenclass
singleton
randombits
источник
источник
Ответы:
Во-первых,
class << foo
синтаксис открываетfoo
одноэлементный класс (собственный класс). Это позволяет вам специализировать поведение методов, вызываемых для этого конкретного объекта.Теперь, чтобы ответить на вопрос:
class << self
открываетсяself
одноэлементный класс, так что методы могут быть переопределены для текущегоself
объекта (который внутри тела класса или модуля является самим классом или модулем ). Обычно это используется для определения методов класса / модуля («статических»):Это также может быть записано как сокращение:
Или даже короче
Когда внутри определения функции,
self
относится к объекту, с которым вызывается функция. В этом случаеclass << self
открывается одноэлементный класс для этого объекта; Одно из применений этого заключается в реализации конечного автомата бедного человека:Таким образом, в приведенном выше примере каждый экземпляр
StateMachineExample
имеетprocess_hook
псевдонимprocess_state_1
, но обратите внимание, как в последнем он может переопределитьprocess_hook
(self
только, не затрагивая другиеStateMachineExample
экземпляры)process_state_2
. Таким образом, каждый раз, когда вызывающаяprocess
сторона вызывает метод (который вызывает переопределениеprocess_hook
), поведение меняется в зависимости от того, в каком состоянии он находится.источник
class << self
для создания методов класса / модуля. Я, вероятно, остановлюсь на этом использованииclass << self
, поскольку это гораздо более идиоматическое использование.a
«S ,singleton_class
так какa
» класса s (после измененияinspect
) представляет собой уникальный вариантString
класса. Если бы он менялString
класс синглтона, это затронуло бы все другиеString
экземпляры. Что еще более странно, так это то, что если вы позже откроетеString
заново,inspect
тоa
все равно поймете новые изменения.class << self
что-либо большее, чем значение,self
установленное равным одноэлементному классу в области видимости блока?Я нашел супер простое объяснение о том
class << self
,Eigenclass
и различных типах методов.В Ruby есть три типа методов, которые можно применять к классу:
Методы экземпляра и методы класса почти аналогичны их одноименным в других языках программирования.
Другой способ доступа к
Eigenclass
(который включает одноэлементные методы) заключается в следующем синтаксисе (class <<
):Теперь вы можете определить одноэлементный метод, для
self
которого является сам классFoo
в этом контексте:источник
foo.singleton_class.instance_methods(false)
чтобы проверить.Обычно методы экземпляра являются глобальными методами. Это означает, что они доступны во всех экземплярах класса, в котором они были определены. Напротив, одноэлементный метод реализован на одном объекте.
Ruby хранит методы в классах, и все методы должны быть связаны с классом. Объект, для которого определен одноэлементный метод, не является классом (это экземпляр класса). Если только классы могут хранить методы, как объект может хранить одноэлементный метод? При создании одноэлементного метода Ruby автоматически создает анонимный класс для хранения этого метода. Эти анонимные классы называются метаклассами, также известными как одноэлементные классы или собственные классы. Метод singleton связан с метаклассом, который, в свою очередь, связан с объектом, для которого был определен метод singleton.
Если в одном объекте определены несколько одноэлементных методов, все они хранятся в одном метаклассе.
В приведенном выше примере класс << z1 изменяет текущее значение self на метакласс объекта z1; затем он определяет метод say_hello в метаклассе.
Классы также являются объектами (экземплярами встроенного класса под названием Class). Методы класса - это не более чем одноэлементные методы, связанные с объектом класса.
Все объекты могут иметь метаклассы. Это означает, что у классов также могут быть метаклассы. В приведенном выше примере class << self изменяет self, поэтому оно указывает на метакласс класса Zabuton. Когда метод определен без явного получателя (класс / объект, для которого будет определен метод), он неявно определяется в текущей области, то есть в текущем значении себя. Следовательно, метод stuff определен в метаклассе класса Zabuton. Приведенный выше пример является еще одним способом определения метода класса. ИМХО, лучше использовать синтаксис def self.my_new_clas_method для определения методов класса, так как это облегчает понимание кода. Приведенный выше пример был включен, чтобы мы понимали, что происходит, когда сталкиваемся с синтаксисом класса << self.
Дополнительную информацию можно найти в этом посте о Ruby Classes .
источник
Что делает класс << вещь:
[это делает
self == thing.singleton_class
в контексте своего блока] .Что такое thing.singleton_class?
hi
объект наследует его#methods
от своего,#singleton_class.instance_methods
а затем от своего#class.instance_methods
.Здесь мы дали
hi
«s одноэлементный класс метод экземпляра:a
. Это можно было сделать с помощью класса << hi .hi
«S#singleton_class
имеет все методы экземпляраhi
» ы#class
есть, и , возможно , еще некоторые (:a
здесь).[методы экземпляра вещи
#class
и#singleton_class
могут быть применены непосредственно к вещи. когда ruby видит thing.a, он сначала ищет: определение метода в thing.singleton_class.instance_methods, а затем в thing.class.instance_methods]Кстати, они называют синглтон-класс объекта == метакласс == собственный класс .
источник
А Синглтон метод это метод , который определен только для одного объекта.
Пример:
Синглтон методы SomeClass
тестовое задание
Синглтон методы test_obj
test_2
test_3
источник
Фактически, если вы пишете какие-либо расширения C для своих проектов Ruby, на самом деле есть только один способ определить метод Module.
Я знаю, что этот собственный бизнес просто открывает все виды других вопросов, чтобы вы могли добиться большего успеха, просматривая каждую часть.
Объекты первыми.
Могу ли я сделать метод для Foo?
Конечно
Что мне с этим делать?
Просто еще один объект.
Вы получаете все методы Object плюс ваш новый.
Просто объект Foo.
Попробуйте посмотреть, что произойдет, если вы создадите foo из других объектов, таких как класс и модуль. С примерами из всех ответов приятно играть, но вам нужно работать с разными идеями или концепциями, чтобы действительно понять, что происходит с тем, как написан код. Так что теперь у вас есть много терминов, чтобы пойти посмотреть.
Singleton, Class, Module, self, Object и Eigenclass были подняты, но Ruby не называет объектные модели таким образом. Это больше похоже на метакласс. Ричард или __ почему показывает вам идею здесь. http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html И если вас унесет, попробуйте поискать Ruby Object Model в поиске. Два видео, которые я знаю на YouTube, это Дейв Томас и Питер Купер. Они тоже пытаются объяснить эту концепцию. Дэйву понадобилось много времени, чтобы получить его, так что не волнуйтесь. Я все еще работаю над этим тоже. Зачем еще я буду здесь? Спасибо за ваш вопрос. Также взгляните на стандартную библиотеку. Он имеет одноэлементный модуль, как FYI.
Это довольно хорошо. https://www.youtube.com/watch?v=i4uiyWA8eFk
источник