favoriete nieuwtje in rails edge

Gepubliceerd op: 20.III.2006 10:08 CET
Categorieën: rails, ruby

In de volgende versie van rails (1.1) worden veel nieuwe dingen geïntroduceerd. Zie voor een continue groeiende lijst het blog bericht van Scott Raymond. Er zitten waanzinnige dingen bij en ik hoop snel weer tijd te hebben (ik zit nu in een verhuizing) om met al dat moois te spelen.

M’n favoriet is delegate. Het is zo’n juweeltje, dat zó voor de hand ligt dat ik me meteen af vroeg waarom dat niet gewoon in ruby zit. Voorbeeldje:

Address = Struct.new(:city, :country)
class Person < Struct.new(:name, :address)
  delegate :city, :to => :address
end

remco = Person.new('remco', Address.new('Amsterdam', 'Nederland'))
p remco.city # => "Amsterdam"

Dus; definieer twee classes Address en Person waar Person een Address bevat en geef in Person direct toegang tot het city attribuut.

Maar waarom is dit zo mooi? Omdat het zo verschikkelijk eenvoudig te maken is! Oh, nee niet meteen in de rails code kijken, zelf maken!

class Module
  def delegate *args
    t = args.pop[:to]
    args.each { |a| module_eval "def #{a}; #{t}.#{a}; end" }
  end
end

Klaar! Een klein vonkelend juweeltje.

Korte uitleg; er wordt in de class Module (de superclass van Class en dus beschikbaar tijdens het definieren van een class), een method met een variable aantal argumenten toegevoegd. Van deze argumenten trekken we de laatste en gaan er vanuit dat dat een Hash is met een element :to. Voor alle overgebleven argumenten maken we instance methodes met dezelfde naam als dat argument welke de methode aanroept in het :to element met dezelfde naam.

Eigenlijk niet zo gek dat dit niet standaard in ruby zit, want het is natuurlijk oneigenlijk gebruik van een Hash om :to => te kunnen schrijven. Maar het is zo mooi..