OSCON 2005 – MetaProgramming

presenation by Glenn Vanderburg

What is meta programming? It’s Programming your programming language

Rubyist have been discovering metaprogramming. Ruby style and idioms are still changing and adapting

Ruby good for metaprogramming b/c

Examples…

attr_reader, attr_writer, and attr_accessor.

if written in ruby attr_reader would be written like (actually written in C )
precode
class Module
def attr_reader(*syms)
syms.each do |sym|
class_eval %{ def #{sym}
@#{sym}
end
}
end
end
/code/pre

Speaker goes through several implementations over time of different ways different people did metaprogramming with ruby.

How to think about metaprogramming

Another way to think about metaprogramming is a new set of conceptual tools for eliminating duplication (and other smells) from your code.

And another way to think about it is how rails does it – almost as if you can talk you code – PersonTable has_a :name

Most DSLs also deal with other things ou don’t usually find in general-purpose languages

Contexts – context for a new set of statements – a new scope (not in 1.8, but in 1.9)
precode
Struct.new(“Interval”, :start, :end) do
def length
@start – @end
end
end
/code/pre

Backend code looks like if you wanted to add it to 1.8
precode
class Struct
initialize(*args, block)
struct_class = #define struct using args
struct_class_class_eval(block) if block_given?
end
end
/code/pre

Another example of context from Systir system testing tool

precode
add_user {
name “Charles”
password “secret”
priviliges normal
}
/code/pre

Commands and Sentences

Multipart complex statements

ex. field(autoinc, :reg_id, pk)
Overall, it’s just a methodcall – the first parameter – the type – is a method call
precode
def autoinc
return FieldType::AutoInc.instance
end
/code/pre

Units

Domain specific – general purpose language deals with scalars – programs must maintain their knowledge
ex 3.days.from_now
Watch out for operator overloading

precode
class Numeric
def days
self * 60
end
end
/code/pre

Large Vocabularies

override method_missing

Usage:
Roman.XXII
Roman.CCIX
precode
class Roman
def self.missing_method(method_id)
str = method_id.id2name
roman_to_int(str)
end
def roman_to_int(string)

end
end
/code/pre

Resources:

http://www.vanderburg.org/Speaking/Stuff/oscon05.pdf
http://hypermetrics.com/rubyhacker/coralbook/

Posted on August 4, 2005 at 5:53 pm by doug · Permalink
In: Uncategorized

Leave a Reply