Metaprogramare în Ruby: define_method, send și Interceptarea cu method_missing în Ruby

Ghid complet pentru metaprogramare în Ruby: generarea dinamică a metodelor în timpul execuției cu define_method, apelul dinamic cu send și interceptarea apelurilor lipsă.

Sintaxă
define_method(:metoda) { ... } | obiect.send(:metoda) | def method_missing(...)

Ruby este considerat standardul de aur în metaprogramare: capacitatea unui program de a inspecta, modifica și genera cod propriu în timpul rulării (Runtime Code Generation). Pe acest mecanism se bazează magia declarativă din Ruby on Rails (cum ar fi găsirea dinamică User.find_by_email).

Generarea automată a metodelor cu define_method
class RaportFinanciar
  # Generăm automat metode pentru mai multe valute fără duplicare de cod:
  [:ron, :eur, :usd, :gbp].each do |moneda|
    define_method("afiseaza_total_#{moneda}") do |suma|
      puts "Total raportat: #{suma} #{moneda.upcase}"
    end
  end

  # Interceptarea metodelor dinamice inexistente prin method_missing:
  def method_missing(nume_metoda, *argumente, &bloc)
    if nume_metoda.to_s.start_with?("salveaza_in_")
      destinatie = nume_metoda.to_s.sub("salveaza_in_", "")
      puts "Salvare automată a raportului către depozitul '#{destinatie}'..."
    else
      super # dacă nu recunoaștem metoda, apelăm eroarea standard
    end
  end

  def respond_to_missing?(nume_metoda, include_private = false)
    nume_metoda.to_s.start_with?("salveaza_in_") || super
  end
end

raport = RaportFinanciar.new
raport.afiseaza_total_eur(1500) # metodă generată de define_method!
raport.salveaza_in_cloud        # metodă interceptată de method_missing!