Meta Ruby: send/define
O curso trata de duas ferramentas de metaprogramação do Ruby: .send e define_method. O ponto de partida é um problema de despacho, em que o método a chamar só é conhecido como dado em tempo de execução. O .send chama qualquer método por um nome guardado num símbolo ou string e repassa argumentos e blocos. Ele também ignora o private, enquanto o public_send o respeita. O define_method cria métodos de instância a partir de um nome e um bloco, muitas vezes num loop. As aulas reimplementam o attr_accessor e leem como o delegate do Rails gera métodos com module_eval.
O que você vai aprender
- ✓Chamar um método por um nome calculado em tempo de execução com .send
- ✓Por que o .send ignora o private e quando usar o public_send
- ✓Gerar métodos de instância com define_method, inclusive num loop
- ✓Reimplementar o attr_accessor com instance_variable_get e instance_variable_set
- ✓Como o delegate do Rails gera métodos com module_eval e uma string de código
Chamando um método por um nome que você ainda não sabe
Toda chamada de método até aqui nesta série teve a forma object.method_name, com method_name digitado no código e fixado quando o arquivo foi escrito. Isso cobre quase tudo, até o método a chamar ser ele mesmo um dado, que só se conhece com o programa rodando.
Ler a aula completa grátis →Currículo
7 aulasChamando um método por um nome que você ainda não sabe
Por que uma chamada comum exige um nome fixo de método e como a metaprogramação trata métodos como dados.
.send: chamando métodos por um nome dinâmico
O .send chama um método por um nome em símbolo ou string, repassando argumentos e blocos.
A ressalva: send ignora o private
O .send ignora o controle de acesso private, o public_send o respeita, e contornar o private na aplicação é cheiro de design.
define_method: gerando métodos a partir de um bloco
O define_method cria métodos de instância a partir de um nome e um bloco, inclusive vários num loop.
Reimplementando attr_accessor com define_method
Monta um attr_accessor em Ruby puro com define_method num loop, já que o original é escrito em C.
Como o delegate do Rails gera métodos
Lê o código do activesupport e mostra o delegate usando module_eval com string e o delegate_missing_to gerando method_missing.
Juntando tudo
Junta num exemplo o define_method num loop, um método privado gerado e o .send alcançando esse método.