From: Robert Klemme Date: 2007-09-07T18:49:19+09:00 Subject: Re: simple way to encapsulate class << self ; attr_accessor :xyz ; end? 2007/9/7, Giles Bowkett : > 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. This might be an indication that you are using the framework wrongly - or that it's the wrong framework for your task. > 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, There is: irb(main):001:0> class Object irb(main):002:1> def add_accessors(*names) irb(main):003:2> class< end irb(main):005:1> end => nil irb(main):006:0> x=Object.new => # irb(main):007:0> x.add_accessors :foo, :bar => nil irb(main):008:0> x.foo=10 => 10 irb(main):009:0> x.bar => nil But there are other solutions as well: if you know the accessors beforehand you can do this module MyExtension attr_accessor :bar end ... some_object.extend MyExtension > 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: > 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. See above. And probably rethink your framework usage. Kind regards robert