James Gray
11/23/2004 3:26:00 PM
On Nov 21, 2004, at 3:28 PM, Iwan van der Kleyn wrote:
> So my question: do you know of any examples on the subject of dynamic
> code generation which would be typical for Ruby and could not be
> easily implemented in languages like Python?
I don't know if this is the kind of thing you're after and I don't know
Python, so I have no idea how it compares, but and interesting example
did come up in my project today.
I'm building a server. When some event happens in the server, it
notifies monitoring code with an Event object. My first crack at that
class looked like:
class Event
CONNECT = "Connect"
LOGIN = "Login"
COMMAND = "Command"
DISCONNECT = "Disconnect"
def initialize( connection, identity,
type, details = nil, time = Time.now )
@connection = connection
@identity = identity
@type = type
@details = details
@time = time
end
attr_reader :connection, :identity, :type, :details, :time
def connect?() @type == CONNECT end
def login?() @type == LOGIN end
def command?() @type == COMMAND end
def disconnect?() @type == DISCONNECT end
end
That worked, of course. However, one of my major goals with this
server is to keep it very open to change. I know for a fact it will be
modified after deployment, so I'm planning ahead.
The problem with the above version comes when I add a new event type.
I provide those little helper methods like command?(), to keep you from
having to write:
if event.type == Event::COMMAND
# ...
# can be written as...
if event.command?
# ...
However, when I decide I need a new event type, I have to add another
constant and a new helper method. That goes against DRY philosophy.
So, I changed the class to:
class Event
CONNECT = "Connect"
LOGIN = "Login"
COMMAND = "Command"
DISCONNECT = "Disconnect"
def initialize( connection, identity,
type, details = nil, time = Time.now )
@connection = connection
@identity = identity
@type = type
@details = details
@time = time
end
attr_reader :connection, :identity, :type, :details, :time
constants.each do |e|
value = const_get e
define_method((e.downcase + "?").to_sym) do
@type == value
end
end
end
Problem solved. Helper methods are now auto-generated from class
constants. Add a new constant, get a new helper method.
Hopefully, that's the kind of thing you are looking for. Good luck
with your paper.
James Edward Gray II