La metaprogramación en Ruby es una técnica que permite escribir código que genera o modifica otros métodos y clases en tiempo de ejecución. Ruby es conocido por su poderosa capacidad de metaprogramación, la cual facilita la creación de código más dinámico y flexible. Esta técnica se utiliza comúnmente para definir métodos de manera dinámica, crear DSLs (Domain-Specific Languages) y construir estructuras de código que no serían posibles con la programación tradicional.
La metaprogramación permite manipular la estructura del programa a través de métodos que pueden definir, eliminar o alterar otros métodos y clases durante la ejecución del programa. En Ruby, se logra utilizando métodos como define_method
, method_missing
, send
, y a través de bloques y eval
.
define_method
Podemos utilizar define_method
para crear métodos de manera dinámica en una clase según ciertos parámetros:
class Persona
# Crear métodos dinámicamente
[:nombre, :edad].each do |atributo|
define_method(atributo) do |valor|
instance_variable_set("@#{atributo}", valor)
end
define_method("mostrar_#{atributo}") do
instance_variable_get("@#{atributo}")
end
end
end
persona = Persona.new
persona.nombre("Juan")
persona.edad(30)
puts persona.mostrar_nombre # Output: "Juan"
puts persona.mostrar_edad # Output: "30"
method_missing
El método method_missing
se utiliza para capturar llamadas a métodos que no existen en el objeto, permitiendo manejar estos casos de manera dinámica.
class MiProxy
def method_missing(nombre, *args, &bloque)
puts "El método '#{nombre}' no existe. Argumentos: #{args}"
end
end
objeto = MiProxy.new
objeto.saludar("Hola") # Output: "El método 'saludar' no existe. Argumentos: ["Hola"]"
send
El método send
permite invocar métodos dinámicamente, incluso si son privados. Es útil para metaprogramación avanzada cuando no se conoce el nombre del método de antemano.
class Ejemplo
private
def saludo
"Hola desde un método privado"
end
end
ejemplo = Ejemplo.new
puts ejemplo.send(:saludo) # Output: "Hola desde un método privado"
class_eval
y module_eval
class_eval
y module_eval
se utilizan para ejecutar código en el contexto de una clase o módulo, permitiendo agregar o modificar métodos y variables.
class Animal
end
Animal.class_eval do
def hablar
"Guau!"
end
end
puts Animal.new.hablar # Output: "Guau!"
Puedes encontrar más información sobre metaprogramación en la documentación oficial de Ruby.
Jorge García
Fullstack developer