Metaprogramação

Muito se fala dessa feature do Ruby, mas não achei nenhum exemplo legal. Talvez eu esteja fazendo alguma burrada.

Tudo que eu quero é escrever uma função para cuspir um código. Não quero criar métodos como todos os exemplos explicam.

Por exemplo, eu quero uma função estática para cuspir um “self.sayBye” no corpo de outro método. Nesse caso o self seria da função onde eu estou cuspindo e não do método estático.

Tem como ou é impossível em Ruby. Em Java é molinho… (brincadeira)

Não entendi o que você quer fazer, dá pra explicar melhor?

Você não pode simplesmente mandar um bloco e fazer yield no outro método?

Metaprogramação, pelo menos em C, é um código que cospi outro código.

Em C eu faço assim:

#define GET_STRING(_resp, _path, _fieldname, _buffer) 			\
	memcpy((&_buffer), (_resp)->_path._fieldname,			\
		 sizeof((_resp)->_path._fieldname));

Então aonde eu colocar GET_STRING ele vai chapar (cuspir) o código acima.

Talvez tudo que eu necessite é dar um include ou require ???

Tentei mais não funcionou. O que eu quero é incluir dinamicamente um bloco de código para ser executado no contexto onde eu estou incluindo.

Como falei: se eu incluir self.sayBye, o self fica sendo do contexto onde ele foi incluído.

Ah tá, você quer macros. Não há nada desse tipo em Ruby, mas provavelmente dá para resolver o seu problema de outra forma. Um mixin não resolve?

Pô, ruby tem tudo menos isso? :frowning:

Meu problema é simples. Eu tenho que escrever um monte de código para fazer uma coisa funcionar.

Ex:


a = Hash.new
a['aaa'] = 'bbb'
...

Queria fazer uma função (macro) que cuspisse isso pra mim. Eu juro que achei que o attr_reader era um macro. :frowning:

Acho que vou ter que fazer um método mesmo, problema: São milhares de possibilidades, ou seja, vou ter que ter milhares de métodos.

Acho que a solução é fazer milhares de módulos e dar include neles.

Vou pensar mais sobre isso… Talvez ler mais sobre Ruby…

Se você não quer criar métodos, pode dar um override no seu method_missing. É assim que Rails faz coisas como User.find_by_name_and_age_and_city

Macros de substituição simple como as de C (ao conrário das macros Lisp) são muito simples, apenas substituição de texto. Se você realmente quier algo do tipo se u pré-processador, dá pra fazer um em algumas linhas de Ruby com overload do método require.

Mas você não vai querer fazer isso :slight_smile:

Override do método require??? Interessante! Só não sei fazer isso… Ainda…

To comprando o livro novo The Ruby Programming Language, da O’Reilly. Espero que seja bom e me ensine a teoria dessas e de outras coisas. O resto é prática!

Dá uma olhada no The Ruby Way també, ensina bastante sobre estilo.