Considere a seguinte classe:
class Foo
def an_inst_method
'instance method'
end
def self.a_class_method
'class method'
end
alias_method :a_new_inst_method, :an_inst_method
end
Isso não é problema e você pode ligar Foo.new.a_new_inst_method
sem problemas.
Eu gostaria da capacidade de ter um método de classe Foo.add_widget(*items)
e o apelido para que eu possa fazer algo como:
Foo.add_widget 'item1'
Foo.add_widgets 'item2', 'item3'
Então, basicamente, ele tem um estilo "ruby" 1.minute
e, 2.minutes
por isso, quero Foo.add_widget
chamar um apelido de chamado Foo.add_widgets
exatamente o mesmo método. Eu sei que poderia envolvê-lo, mas sinto que deveria ser capaz de fazer isso de uma maneira mais limpa.
Considere minha tentativa de tentar algo como isto:
class Foo
def an_inst_method
'instance method'
end
def self.a_class_method
'class method'
end
alias_method :a_new_inst_method, :an_inst_method
alias_method :a_new_class_method, :a_class_method
end
No entanto, eu recebo o seguinte erro:
NameError (undefined method `a_class_method' for class `Foo')
E assim parece que isso não funciona para métodos de classe. Como faço para fazer isso?
fonte
extend ClassMethods
solução. +1O importante é entender que não existe um método de classe no Ruby.
Um método de classe é realmente apenas um método singleton. Não há nada de especial nos métodos de classe. Todo objeto pode ter métodos singleton. Apenas os chamamos de "métodos de classe" quando o objeto é um
Class
"método singleton de uma instância deClass
" é muito longo e pesado.Esperar! Eu disse "método singleton"?
Outra coisa importante a entender é que não existe um método singleton no Ruby.
Um método singleton é realmente apenas um método de instância antigo e chato da classe singleton. Não há nada de especial nos métodos singleton. Eles são apenas métodos de instância como qualquer outro método de instância.
De fato, Ruby possui apenas métodos de instância. Sem funções, sem construtores, sem métodos estáticos, sem métodos de classe, sem funções de módulo, sem métodos singleton.
A questão não é "este é um método de classe, é um método singleton", mas "em que módulo esse método está definido?"
"Métodos Singleton" são realmente métodos de instância definidos na classe singleton. A sintaxe para acessar a classe singleton de
foo
éHá também um método
Object#singleton_class
que retorna a classe singleton de um objeto.Por que estou tão agressivamente insistindo no fato de que todo método é um método de instância e que métodos de classe não existem? Porque isso significa que o modelo de objetos de Ruby é muito mais simples do que as pessoas pensam! Afinal, na sua pergunta, você já mostra que sabe alias métodos de instância, mas diz que não sabe alias métodos de classe. Mas isso está errado! Você fazer saber como métodos de classe apelido, porque eles são apenas métodos de instância . Se você tivesse aprendido esse fato adequadamente, nunca precisaria fazer essa pergunta!
Depois que você entende que todo método é um método de instância e que chamamos de "métodos singleton" são apenas métodos de instância da classe singleton, a solução fica clara:
Nota: quando escrevi acima que "não existe X", o que eu quis dizer foi "não existe X na linguagem Ruby ". Isso não significa que esses conceitos não existam na comunidade Ruby .
Falamos regularmente sobre "métodos singleton" e "métodos de classe", simplesmente porque é mais fácil do que falar sobre "métodos de instância da classe singleton" ou "métodos de instância da classe singleton de um objeto que por acaso é uma instância da
Class
classe " Há até mesmo métodos, comoObject#define_singleton_method
,Object#singleton_method
,Object#singleton_methods
,Module#private_class_method
,Module#public_class_method
, eModule#module_function
na biblioteca núcleo Ruby. Mas é sempre importante lembrar que esses não são conceitos de linguagem. Esses são conceitos de comunidade que existem apenas em nossas cabeças e nos nomes de alguns métodos de biblioteca.fonte
OK, parece que posso fazer algo assim e funcionará:
Se alguém tiver alguma informação útil sobre o idioma Ruby aqui e quiser enviar uma resposta abrangente, darei um +1.
fonte
class << self
segue,alias_method :a_new_class_method, :a_class_method
você realmente chamaalias_method
a classe singleton deFoo
. Outra maneira de escrever isso é:singleton_class.alias_method :a_new_class_method, :a_class_method
no contexto da classe.alias_method
opera na instância, então você precisa ir um nível mais fundo e operar naClass
instância ou na metaclasse da classe . Ruby tem um modelo de objeto selvagem que pode ser uma espécie de quebra de cérebro, mas também oferece uma tonelada de poder:fonte