C
Charles Comstock
I recently wrote a small compiler in java in which we used the visitor
design pattern to walk an abstract syntax tree hiearchy. I was most
impressed with the ease with which a reflective visitor allowed me to
walk the tree. So recently having some free time I set about to
implement a similar visitor pattern for Ruby, which could easily be
dropped in as a module. I believe the code below does this in a
reasonably elegant fasion. I have examples of it's use posted at the
bottom of http://www.rubygarden.org/ruby?VisitorPattern I thought it
an interesting solution for implementing double-dispatch, while still
providing alot of power and flexability. I was curious considering
the existing design patterns in the ruby library (Observer, Singleton,
etc.) if there was any interest in including this design pattern as well?
Whether or not there is interest, I was curious what, if any thread
safety or exception handling anyone would suggest in this code, or if
it should simply be handled by visitor code that uses this library.
Thanks,
Charles Comstock
#file visitor.rb
module Visitable
def accept(visitor,&block)
for klass in self.class.ancestors do
break if (v = visitor.methods.include?("visit_#{klass}"))
end
if v
visitor.__send__("visit_#{klass}",self,&block)
else
visitor.default_visit(self,&block)
end
end
def Visitable.included(kls)
kls.module_eval <<-"end_eval"
def self.inherited(child)
child.module_eval "include Visitable"
end
end_eval
end
end
design pattern to walk an abstract syntax tree hiearchy. I was most
impressed with the ease with which a reflective visitor allowed me to
walk the tree. So recently having some free time I set about to
implement a similar visitor pattern for Ruby, which could easily be
dropped in as a module. I believe the code below does this in a
reasonably elegant fasion. I have examples of it's use posted at the
bottom of http://www.rubygarden.org/ruby?VisitorPattern I thought it
an interesting solution for implementing double-dispatch, while still
providing alot of power and flexability. I was curious considering
the existing design patterns in the ruby library (Observer, Singleton,
etc.) if there was any interest in including this design pattern as well?
Whether or not there is interest, I was curious what, if any thread
safety or exception handling anyone would suggest in this code, or if
it should simply be handled by visitor code that uses this library.
Thanks,
Charles Comstock
#file visitor.rb
module Visitable
def accept(visitor,&block)
for klass in self.class.ancestors do
break if (v = visitor.methods.include?("visit_#{klass}"))
end
if v
visitor.__send__("visit_#{klass}",self,&block)
else
visitor.default_visit(self,&block)
end
end
def Visitable.included(kls)
kls.module_eval <<-"end_eval"
def self.inherited(child)
child.module_eval "include Visitable"
end
end_eval
end
end