Reflection: Acertando o avião em pleno voo

jul 18 2009

Um dos recursos mais legais de programação, é o recurso de metaprogramação! =D Mas uma coisa que sempre rola na internet é a questão: “qual o nome correto: reflexão, introspecção ou metaprogramação?”. Basicamente, faz algum sentido para os três existirem, não?

Podemos começar definindo metaprogramação: Metaprogramação é a construção de metaprogramas. Um metaprograma é um programa que gera outro programa. Aqui temos que: um programa pode ser comum (escrito em uma linguagem de programação), pode ser um metaprograma (escrito em uma metalinguagem de programação) ou pode ser um programa-objeto (gerado por um metaprograma). Mais um conceito agregado: metalinguagem.

Agora podemos definir reflexão. Reflexão é a capacidade de uma linguagem de programação comum assumir a forma de metalinguagem. E a reflexão se divide em dois tipos: introspecção e intercessão. :) Caramba! Quanto nome, não? O fato é que para cada linguagem você vai ver um nome diferente. Em Python, todo mundo chama introspecção, mesmo quando estamos falando de intercessão. Java é tudo reflexão, mesmo Java não suportando interecessão. Em Ruby, é tudo metaprogramação. Anyway, o nome não importa, por isso não vou me prender ao nome, vou apenas dar algumas demonstrações :)

Gerar programas, classes, métodos, funções e estruturas dinâmicas em tempo de execução, isso é a essência da metaprogramação. É como fazer o avião efetivamente funcionar quando ele já está no ar (os riscos são menores com metaprogramação :P).

Enfim, para uma rápida demonstração de reflection (termo que gosto mais de usar :P) em Python, vou definir em tempo de execução uma classe chamada Pessoa, com os atributos nome e idade, e os métodos mudar_de_nome e envelhecer. Tudo será definido em tempo de execução! Queria muito fazer isso em Java, mas Java não da suporte a intercessão (que é efetivamente interceder, alterar, modificar. Introspecção seria apenas obter informações, sem alterá-las em sua fonte). Veja como ficou:

def envelhecer(self):
    self.idade += 1

def mudar_de_nome(self, novo_nome):
    self.nome = novo_nome

Pessoa = type('Pessoa', (), {})
Pessoa.nome = ''
Pessoa.idade = 0
Pessoa.envelhecer = envelhecer
Pessoa.mudar_de_nome = mudar_de_nome

p = Pessoa()
p.mudar_de_nome('Francisco')
p.idade = 20
p.envelhecer()

Muito simples, não?! :) Tudo isso por que Python da um suporte quase transparente à “metaprogramação”, mas só neste caso. Existem casos mais complexos para Python, que podem ser explorados numa próxima oportunidade. :)

One response so far

  1. [...] on Rails, agile e outras coisas mais Pular para o conteúdo InícioSobreComunidadeContato ← Reflection: Acertando o avião em pleno voo JasperReports com JRBeanCollectionDataSource [...]

Leave a Reply

Spam protection by WP Captcha-Free