From: Sean O'Halpin Date: 2008-05-11T03:29:58+09:00 Subject: Re: Reading from file, create a class with variables On Sat, May 10, 2008 at 5:44 PM, ara.t.howard wrote: > class Specd > alias_method '__eval__', 'instance_eval' > > instance_methods.each{|m| undef_method m unless m[%r/__/]} D'oh! Overlooked the obvious. > > the point of blowing away all the methods in spec'd is so i can intercept > any DSL-ish methods and apply them to the class i'm building. using this > sort of DSL wrapper allows me to build up a class with a dsl without > littering the class itself with useless DSL crap. Namespaced methods would help. Agreed about littering - I'm currently refactoring doodle to be as unobtrusive as possible. > > class Model > > has_many :foos > > end > > relies on Model having a has_many method. this is sometimes not desirable > as it may require, for instance, inheriting from some abstract base type. > with the 'dsl as wrapper approach' one can do > > Model = DSL.build do > > has_many :foos > > end > > and Model can be a totally 'normal' class - all the special DSL-y goodness > on how to build up stuff is contained in the DSL object, which has a @model > instance and all methods stripped except the dsl ones. You could also have DSL(Model) do has_many :foos end or the like to decorate existing classes. I'm using a similar approach in one of my 'least footprint' experimental versions of doodle. In miniature, something like this: class ClassExtensions attr_accessor :model def initialize(model, &block) @model = model end # DSL method def has(*args) model.class_eval { attr_accessor(*args) } end end def DSL(klass, &block) ce = ClassExtensions.new(klass) ce.instance_eval(&block) end class Foo end DSL(Foo) do has :name end foo = Foo.new foo.name = 'Trillian' foo.name # => "Trillian" p Foo.methods - Object.methods # >> [] which is basically the same approach as yours I believe. > this code works very similarly > > http://codeforpeople.com/lib/ruby/configuration/configuration-0.0.5/lib/configuration.rb > Yup, and very instructive it is too :) Regards, Sean