On Jan 4, 2008 6:43 AM, David A. Black <dblack / rubypal.com> wrote: > Hi -- > > > On Fri, 4 Jan 2008, Brian Mitchell wrote: > > > On Jan 3, 2008 10:06 PM, Sam Ruby <rubys / intertwingly.net> wrote: > >> I'm looking at converting some code over from BlankSlate to BasicObject, > >> but hit a roadblock: I can't figure out any way to do the equivalent of > >> > >> class Foo < BlankSlate > >> def initialize > >> @secret = 99 > >> end > >> end > >> > >> foo = Foo.new > >> foo.instance_eval {@secret} > >> > >> Any suggestions? > > > > Interesting situation. Part of me would want Ruby to allow something like: > > > > # Doesn't work obviously... > > Object.instance_method(:instance_eval).bind(foo).call {@secret} > > > > On the other hand, it isn't hard to write a method that can be used to > > extract information w/o dirtying the interface: > > > > class << BasicObject > > def accessor_for(name) > > @accessors_for ||= {} > > unless @accessors_for[name] > > tmp = "__tmp#{Thread.current.object_id}__" > > class_eval %[ > > def #{tmp} > > #{name} > > end > > ] > > accessors_for[name] = instance_method(tmp) > > undef_method(tmp) > > end > > lambda {|obj| @accessors_for[name].bind(obj).call} > > end > > end > > > > Now you can use: > > > > BasicObject.accessor_for('@test').call(foo) > > However, until the question of the metaclass/Class thing is resolved, > you end up with this: > > irb(main):001:0> class << BasicObject; def x; 1; end; end > => nil > irb(main):002:0> String.x > => 1 > > In other words, #accessor_for will be defined directly on Class. As > per the other thread, I believe this must be a bug, but I'm waiting > for a pronouncement. Good catch. I think it might be related to [ruby-core:14690]. Brian.