From: "ara.t.howard" Date: 2008-10-26T13:41:52+09:00 Subject: Re: Object#instance_eval but better On Oct 24, 2008, at 11:55 AM, Richard Crowley wrote: > have a bit of code here that I'd love to make better: > > class Foo > def initialize(path) > self.instance_eval(File.read(path)) > end > end > > I don't want to continue down the path of reading an entire file > into a string and then eval'ing that string just to get the contents > of the file executed as if it were the body of a method in a class. > The file passed to the constructor above might contain something like: > > @foo = 'This will become an instance variable when you do > Foo.new(path)' > > I've tried all manner of hacks to make Kernel#load and friends > execute code as if it were in the calling scope. In every case I've > seen the loaded file leave no lasting effect on the instance > variables of the calling method. My goal is to be able to do > exactly this: reverse your logic: don't force the code to eval inside a context - provide the context. cfp:~ > cat a.rb class Foo class << self attr_accessor :current def initializing &block caller = eval 'self', block if caller.is_a?(Foo) previous = current begin Foo.current = caller block.call ensure Foo.current = previous end else current.instance_eval &block end end end def initialize path Foo.initializing{ load path } end end foo = Foo.new('b.rb') p foo.instance_variables cfp:~ > cat b.rb Foo.initializing do @foo = 42 end cfp:~ > ruby a.rb ["@foo"] a @ http://codeforpeople.com/ -- we can deny everything, except that we have the possibility of being better. simply reflect on that. h.h. the 14th dalai lama