Para quem como eu, vem de linguagens não-dinâmicas, o que mais impressiona (e dificulta no início) é a capacidade de Ruby em se moldar e executar códigos dinamicamente. E seguindo a nossa saga pelos conceitos de metaprogramação, vamos explorar um pouco mais um recurso interessantíssimo de Ruby chamado eval.
Ruby Eval
O nome eval tem origem na palavra inglesa evaluation, que em uma tradução livre significa “avaliar o valor de algo”, no caso de Ruby, o valor de uma expressão ou trecho de código.
No caso de Ruby, a melhor definição seria “interpretar”, devido ao fato que além de avaliar, o código recebido também é executado, como no exemplo abaixo:
eval("puts 'Hello World'") # => Hello World
No post anterior sobre metaprogramação, eu utilizei o método instance_variable_set da classe Object.
Esse método pode ser utilizado para evitar repetições de código. No código abaixo eu mostro como é a implementação desse método e como ele é usado na prática:
Implementação redundante de um construtor de uma classe:
class CalendarEvent
def initialize(start_time=0, end_time=0, attendees=0)
@start_time = start_time
@end_time = end_time
@attendees = attendees
end
end
Implementação melhorada com o uso de eval:
#Primeiro, adicionamos o seguinte código à classe Object,
#para torná-lo disponível para as instâncias de quaisquer classe
class Object
private
def set_instance_variables(binding, *variables)
variables.each do |var|
instance_variable_set("@#{var}", eval(var, binding))
end
end
end
#Depois podemos melhorar a nossa classe
class CalendarEvent
def initialize(start_time=0, end_time=0, attendees=0)
set_instance_variables(binding, *local_variables)
end
end
c = CalendarEvent.new(4,5,2)
puts c.instance_eval "@start_time" # => 4



