Abaixo segue o primeiro contato que fiz sobre assunto “Reflexão em Ruby”, espero que gostem e aguardo críticas!!!
Uma grande vantagens de linguagens dinâmicas como Ruby é a habilidade para instropecção – para examinar aspectos do programa a partir de dentro do próprio programa. Em Java, por exemplo, exige de reflection, enquanto que no Ruby é possível ir mais além.
A palavra reflection assemelha-se reflexo no espelho, uma imagem de si mesmo – No Ruby existe a possibilidade de verificar os objetos que estão “vivos” em seu programa. Conforme o exemplo abaixo:
a = 95.1
b = 102.7
#Obtendo os objetos do tipo Numeric(Float) e através do bloco de código
# é imprimindo os valores que estão em memória
ObjectSpace.each_object(Numeric) {|x| p x}
Entretanto, os alguns objetos não podem ser visto, que são: Fixnum, Symbol, true, false e nil.
Olhando através do Objeto
Depois de encontrar um objeto de seu interesse, que podemos fazer é saber exatamente o que ele pode fazer. Ao instanciar um objeto podemos obter uma lista de todos os metodos do objeto, segue abaixo um exemplo:
# Cria um objeto Range
r = 1..10
# Obtem uma lista de todos os metodos do objeto “r”
list = r.methods
# Quantidade objetos no array
list.lenght –> 68
list[0..3] –> ["collect", "to_a", "instance_eval", "eval"]
Ou, Nós podemos checar se um objeto suporta um metodo particular.
r.respond_to(“frozen”) –> true
r.respond_to(:has_key?) –> false
“me”.respond_to?(“==”) –> true
Podemos determinar apartir de nosso objeto a classe a qual pertence, o seu object ID e testar a sua relação com outras classes.
num = 1
num.id –> 3
num.class –> Fixnum
num.kind_of? Fixnum –> true
num.kind_of? Numeric –> true
num.instance_of? Fixnum –> true
num.instance_of? Numeric –> false
Analisando as classes
Saber sobre objeto é apenas uma tipo de reflexão, mas para obter toda imagem, você também precisa ser capaz de olhar para classes – os métodos e constantes que elas contêm. Olhando para a hierarquia de classe é fácil. Você pode obter o pai de qualquer classe em particular basta usar class#superclass. Para classes e módulos, module#ancestors lista ambos superclasses e modules mixed-in. Exemplo:
klass = Fixnum
begin
print klass
klass = klass.superclass
print ” < ” if klass
end while klass
p Fixnum.ancestors
Referência Bibliográfica
THOMAS, D.; FOWLER, C.; HUNT, A. Programming Ruby. 2st. ed. [S.l.]: Pragmatic Bookshelf, 2004.