La metaprogramació és una tècnica avançada en Ruby que permet al codi escriure codi. Això significa que pots crear mètodes i classes dinàmicament durant l'execució del programa. Aquesta capacitat fa que Ruby sigui extremadament flexible i potent, però també pot complicar el codi si no es fa servir amb cura.

Conceptes Clau

  1. Definició Dinàmica de Mètodes: Crear mètodes durant l'execució del programa.
  2. define_method: Un mètode que permet definir altres mètodes dinàmicament.
  3. method_missing: Captura les trucades a mètodes que no existeixen.
  4. send i __send__: Permet trucar a mètodes, incloent-hi els privats.
  5. eval: Executa codi Ruby que es passa com a cadena de text.

Definició Dinàmica de Mètodes

define_method

El mètode define_method permet definir mètodes dinàmicament. Aquí tens un exemple:

class Persona
  def initialize(nom)
    @nom = nom
  end

  define_method(:saluda) do
    "Hola, #{@nom}!"
  end
end

persona = Persona.new("Anna")
puts persona.saluda  # Sortida: Hola, Anna!

method_missing

El mètode method_missing es crida quan es fa una trucada a un mètode que no existeix. Això permet capturar aquestes trucades i gestionar-les de manera personalitzada.

class Persona
  def method_missing(metode, *args)
    puts "El mètode #{metode} no existeix, però aquí tens els arguments: #{args.join(', ')}"
  end
end

persona = Persona.new
persona.saluda("Anna")  # Sortida: El mètode saluda no existeix, però aquí tens els arguments: Anna

send i __send__

Els mètodes send i __send__ permeten trucar a mètodes, incloent-hi els privats. Això pot ser útil en situacions on necessites accedir a mètodes privats des de fora de la classe.

class Persona
  private
  def secret
    "Aquest és un secret!"
  end
end

persona = Persona.new
puts persona.send(:secret)  # Sortida: Aquest és un secret!

eval

El mètode eval permet executar codi Ruby que es passa com a cadena de text. Això pot ser molt potent, però també perillós si s'utilitza amb dades no confiables.

codi = "2 + 2"
resultat = eval(codi)
puts resultat  # Sortida: 4

Exercicis Pràctics

Exercici 1: Definició Dinàmica de Mètodes

Crea una classe Calculadora que defineixi dinàmicament mètodes per sumar, restar, multiplicar i dividir dos números.

class Calculadora
  [:suma, :resta, :multiplica, :divideix].each do |operacio|
    define_method(operacio) do |a, b|
      case operacio
      when :suma
        a + b
      when :resta
        a - b
      when :multiplica
        a * b
      when :divideix
        a / b
      end
    end
  end
end

calculadora = Calculadora.new
puts calculadora.suma(5, 3)        # Sortida: 8
puts calculadora.resta(5, 3)       # Sortida: 2
puts calculadora.multiplica(5, 3)  # Sortida: 15
puts calculadora.divideix(6, 3)    # Sortida: 2

Exercici 2: method_missing

Crea una classe Persona que utilitzi method_missing per gestionar trucades a mètodes inexistents i imprimeixi un missatge personalitzat.

class Persona
  def method_missing(metode, *args)
    puts "El mètode #{metode} no existeix, però aquí tens els arguments: #{args.join(', ')}"
  end
end

persona = Persona.new
persona.diu("Hola")  # Sortida: El mètode diu no existeix, però aquí tens els arguments: Hola

Resum

La metaprogramació en Ruby és una eina poderosa que permet crear codi dinàmicament. Hem vist com utilitzar define_method per definir mètodes dinàmicament, method_missing per capturar trucades a mètodes inexistents, send per trucar a mètodes privats i eval per executar codi Ruby des de cadenes de text. Aquests conceptes són fonamentals per aprofitar al màxim la flexibilitat de Ruby, però s'han d'utilitzar amb cura per evitar complicacions innecessàries en el codi.

© Copyright 2024. Tots els drets reservats