On Sep 7, 2:24 am, "Giles Bowkett" <gil... / gmail.com> wrote: > I'm writing some code which works in the context of a very popular Web > framework and yet bumps against limitations in that framework several > times a day. One thing I have to do **constantly** is this: > > def foo > class << bar > attr_accessor :baz > end > do_stuff(bar.baz) > end > > or sometimes even > > def foo > instance_eval do > class << self > attr_accessor :bar > end > end > do_stuff(bar) > end > > This pattern gets ugly fast. It would be so much easier if I could just do > > foo.add_accessor(:bar) > > and get the same functionality as > > class << foo > attr_accessor :bar > end > > so I tried to graft this onto the base object: > > class BaseObject > def add_methods(methods) > class << self > attr_accessor methods > end > end > end > > But that blew up on me. There's two flaws in that. The first is that > methods is already a method name, so using it as a variable name was a > pretty dumb idea. The second is that the arg to the method isn't > visible once you're inside that class << self block. > > It doesn't seem as if there's any way to do it without using #eval, > and frankly, using #eval is so last month. Who uses #eval any more? > That's like Fred Flintstone style. > > Nonetheless, here's how you can do it with eval: > > class Base > def add_xsor(xsor) > eval("class << self ; attr_accessor :#{xsor} ; end") > end > end > > class Boat < Base ; end > boat = Boat.new > boat.add_xsor(:need) > boat.need = "bigger" > > The big flaw here, of course, is that it only works on instances, but > in practical terms I always seem to use it in an instance context. > > I'm going to have to use this code for the time being but I'm > definitely on the lookout for a better way to do it. It's clean, but > not totally satisfying. module Kernel def meta class << self; self; end end end class Module public :attr_accessor, :attr_reader, :attr_writer end then def foo meta.attr_accessor :x end T.