rails.se
Invitation till Rubys metaprogrammering

Metaprogrammering

Mycket av Rubys makt kommer från dess introspektion och möjligheter att skriva om klasser – inte endast instanser – under körning.

Därför finns Ruby on Rails: introspektion (reflektion) är relativt smärtfri med Ruby. (Trivial, om man jämför med Java.)

Siffran 1 är som bekant ett objekt, och att avgöra dess klass är ett anrop till class. Efter det frågar vi vilka metoder som objektet har, i bokstavsordning.


irb(main):004:0> 1.class
=> Fixnum
irb(main):005:0> 1.methods.sort
=> ["%", "&", "*", "**", "+", "+@", "-", "-@", "/", "<", "<<", "<=", 
"<=>", "==", "===", "=~", ">", ">=", ">>", "[]", "^", "__id__", 
"__send__", "abs", "between?", "ceil", "chr", "class", "clone", 
"coerce", "display", "div", "divmod", "downto", "dup", "eql?", 
"equal?", "extend", "floor", "freeze", "frozen?", "hash", "id", 
"id2name", "inspect", "instance_eval", "instance_of?", 
"instance_variable_get", "instance_variable_set", "instance_variables",
"integer?", "is_a?", "kind_of?", "method", "methods", "modulo", "next", "nil?",
"nonzero?", "object_id", "prec", "prec_f", "prec_i", "private_methods",
"protected_methods", "public_methods", "quo", "remainder", "respond_to?",
"round", "send", "singleton_method_added", "singleton_methods", "size",
"step", "succ", "taint", "tainted?", "times", "to_a", "to_f", "to_i", "to_int", "to_s",
"to_sym", "truncate", "type", "untaint", "upto", "zero?", "|", "~" 

Lite om arv

Alla klasser är vidöppna

Med method_missing kan kolla om det finns behov av att skapa nya metoder. Mest berömt för detta är väl Rails’ sätt att skapa metoder från den meta-data som läses upp ur applikationens databas. find_by_skostorlek kan på det sättet göras till en fullvärdig metod på modellobjekten.

Mixins

“Jag mixar hellre in än subklassar”, sa Sean.

Hur man undviker trafikkaos i modulerna

Aliasa gamla metoder, och ge tillbaka den gamla funktionaliteten när man går ur den omdefinierande metoden.

Block och yield

Generator#yield

Resurser på nätet

WhyTheLuckyStiff? har skrivit ett stycke kod som heter MetAid (Live Aid, va, men “Meta Aid”). Det återfinns som ett tillägg till hans Guide till Ruby. Dwemthy’s Array, tror jag det hette, det kapitlet

Chapter 6: Downtown handlar också om metaprogrammering.

RubyDoc.org

Bibliotek

Traits är ett experimentellt bibliotek som utökar din Ruby med pre- och post-hookar:

Traits now supports a whole slew of hooks that can be registered to fire pre or post setting an attribute, to cast a value to another type, to munge a value destructively, to require only certain types, to require a certain ducktype signature, and to validate arguments passed. check out sample/m.rb, sample/n.rb, or sample.o.rb to see it in action. the mechanism is quite flexible allowing method names, lambdas of varying arity, and lists of either/or to be passed to any hook.

Se även: Debatt om Rubys metaprogrammering