O que class << self
faz em Ruby ?
ruby
metaclass
eigenclass
singleton
randombits
fonte
fonte
Respostas:
Primeiro, a
class << foo
sintaxe abre afoo
classe singleton (classe própria). Isso permite que você especialize o comportamento dos métodos chamados nesse objeto específico.Agora, para responder à pergunta:
class << self
abreself
's única classe, de modo que os métodos podem ser redefinidos para o atualself
objeto (que dentro de um corpo de classe ou módulo é a classe ou módulo em si ). Normalmente, isso é usado para definir métodos de classe / módulo ("estático"):Isso também pode ser escrito como uma abreviação:
Ou ainda mais curto:
Quando dentro de uma definição de função,
self
refere-se ao objeto com o qual a função está sendo chamada. Nesse caso,class << self
abre a classe singleton para esse objeto; um uso disso é implementar a máquina de estado de um homem pobre:Portanto, no exemplo acima, cada instância de
StateMachineExample
tem umprocess_hook
aliasprocess_state_1
, mas observe como, no último, ele pode redefinirprocess_hook
(self
apenas por não afetar outrasStateMachineExample
instâncias) paraprocess_state_2
. Portanto, cada vez que um chamador chama oprocess
método (que chama de redefinívelprocess_hook
), o comportamento muda dependendo do estado em que ele está.fonte
class << self
, para criar métodos de classe / módulo. Provavelmente vou expandir esse uso declass << self
, pois esse é um uso muito mais idiomático.a
ésingleton_class
desdea
's classe (após a mudançainspect
) é uma variante única daString
classe. Se estivesse mudando aString
classe singleton , isso afetaria todas as outrasString
instâncias. O mais estranho ainda é que se você reabrir mais tardeString
para redefinirinspect
,a
ainda assim receberá as novas alterações.class << self
nada média mais do que o valorself
é definido igual à classe singleton dentro do escopo do bloco?Encontrei uma explicação super simples sobre
class << self
,Eigenclass
e vários tipos de métodos.No Ruby, existem três tipos de métodos que podem ser aplicados a uma classe:
Os métodos de instância e métodos de classe são quase semelhantes aos homônimos em outras linguagens de programação.
Outra maneira de acessar um
Eigenclass
(que inclui métodos singleton) é com a seguinte sintaxe (class <<
):agora você pode definir um método singleton para o
self
qual é aFoo
própria classe neste contexto:fonte
foo.singleton_class.instance_methods(false)
para verificar.Geralmente, métodos de instância são métodos globais. Isso significa que eles estão disponíveis em todas as instâncias da classe em que foram definidas. Por outro lado, um método singleton é implementado em um único objeto.
Ruby armazena métodos em classes e todos os métodos devem ser associados a uma classe. O objeto no qual um método singleton é definido não é uma classe (é uma instância de uma classe). Se apenas classes podem armazenar métodos, como um objeto pode armazenar um método singleton? Quando um método singleton é criado, Ruby cria automaticamente uma classe anônima para armazenar esse método. Essas classes anônimas são chamadas de metaclasses, também conhecidas como classes singleton ou autoclasses. O método singleton está associado à metaclasse que, por sua vez, está associada ao objeto no qual o método singleton foi definido.
Se vários métodos singleton forem definidos em um único objeto, todos serão armazenados na mesma metaclasse.
No exemplo acima, a classe << z1 altera o self atual para apontar para a metaclasse do objeto z1; em seguida, define o método say_hello na metaclasse.
Classes também são objetos (instâncias da classe interna chamada Class). Os métodos de classe nada mais são do que métodos singleton associados a um objeto de classe.
Todos os objetos podem ter metaclasses. Isso significa que as classes também podem ter metaclasses. No exemplo acima, a classe << self modifica a si mesma, de modo que aponta para a metaclasse da classe Zabuton. Quando um método é definido sem um receptor explícito (a classe / objeto no qual o método será definido), ele é definido implicitamente no escopo atual, ou seja, o valor atual de self. Portanto, o método stuff é definido dentro da metaclasse da classe Zabuton. O exemplo acima é apenas outra maneira de definir um método de classe. IMHO, é melhor usar a sintaxe def self.my_new_clas_method para definir métodos de classe, pois isso facilita a compreensão do código. O exemplo acima foi incluído para que possamos entender o que está acontecendo quando encontramos a auto-sintaxe da classe <<.
Informações adicionais podem ser encontradas neste post sobre Ruby Classes .
fonte
Que classe << coisa faz:
[faz
self == thing.singleton_class
no contexto de seu bloco] .O que é o thing.singleton_class?
hi
herda objeto seus#methods
a partir da sua#singleton_class.instance_methods
e, em seguida, a partir da sua#class.instance_methods
.Aqui demos
hi
's única classe método de instância:a
. Poderia ter sido feito com a classe << oi .hi
's#singleton_class
tem todos os métodos de instânciahi
' s#class
tem, e, possivelmente, um pouco mais (:a
aqui).[métodos de instância de coisa
#class
e#singleton_class
podem ser aplicados diretamente a coisa. quando ruby vê thing.a, primeiro procura: uma definição de método em thing.singleton_class.instance_methods e depois em thing.class.instance_methods]A propósito - eles chamam a classe singleton do objeto == metaclass == eigenclass .
fonte
Um método singleton é um método definido apenas para um único objeto.
Exemplo:
Métodos de SingClon de SomeClass
teste
Métodos de singleton de test_obj
test_2
test_3
fonte
De fato, se você escrever qualquer extensão C para seus projetos Ruby, na verdade, existe apenas uma maneira de definir um método Module.
Eu sei que esse negócio próprio apenas abre todos os tipos de outras perguntas para que você possa fazer melhor pesquisando cada parte.
Objetos primeiro.
Posso criar um método para foo?
Certo
O que eu faço com isso?
Apenas outro objeto.
Você obtém todos os métodos Object, além do seu novo.
Apenas o objeto foo.
Tente ver o que acontece se você criar foo de outros objetos como classe e módulo. É bom brincar com os exemplos de todas as respostas, mas você precisa trabalhar com idéias ou conceitos diferentes para realmente entender o que está acontecendo com a maneira como o código é escrito. Então agora você tem muitos termos para analisar.
Singleton, Class, Module, self, Object e Eigenclass foram criados, mas Ruby não nomeia Object Models dessa maneira. É mais como Metaclass. Richard ou __por que mostra a idéia aqui. http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html E se você ficar impressionado, tente pesquisar o Ruby Object Model na pesquisa. Dois vídeos que eu conheço no YouTube são Dave Thomas e Peter Cooper. Eles também tentam explicar esse conceito. Dave demorou muito tempo para obtê-lo, então não se preocupe. Eu ainda estou trabalhando nisso também. Por que mais eu estaria aqui? Obrigado pela sua pergunta. Também dê uma olhada na biblioteca padrão. Possui um módulo Singleton, assim como um FYI.
Isso é muito bom. https://www.youtube.com/watch?v=i4uiyWA8eFk
fonte