From: David Masover Date: 2008-08-17T05:28:56+09:00 Subject: Re: More autoload... On Saturday 16 August 2008 12:55:42 David Masover wrote: > On Saturday 16 August 2008 07:33:22 Trans wrote: > > > It is a serious issue with one of > > my programs. Because of it I am forced never to use autoload, and tell > > all users of my program that they must do the same. > > I think I've found a solution, for myself -- basically a const_missing hack. Ok, that didn't work. All kinds of edge cases, and I can see why things like autoload have been written. So I wrote my own... but there's still one problem I can't seem to solve here: class AutoLoader < BasicObject def initialize parent, mod, file @parent, @mod, @file = parent, mod, file end end # Pushed out here so I can get at Kernel.require. AutoLoader.send :define_method, :method_missing do |*args, &block| @parent.send :remove_const, @mod Kernel.require @file @parent.const_get(@mod).send *args, &block end Typical usage would be: self.class.const_set :Foo, AutoLoader.new(self.class, :Foo, 'foo') And it works great -- exactly the way I want -- for _almost_ all cases. I still can't do this: module Foo end without actually loading foo.rb yet. (Somehow, Ruby knows my BasicObject isn't a module, without ever tripping the method_missing there.) Yet the same thing _does_ work with autoload: autoload :Foo, 'foo' module Foo; end For what it's worth, Rails' const_missing has an even worse problem: If I do the "module Foo" syntax above, I will define Foo, which means const_missing will never be triggered, which means foo.rb will never be loaded. It looks like my choices are either to learn to write a (non-portable) C extension (and maybe still not have it work?), or to create a temporary file, point autoload at that, and have it do the rest. That sucks. Is there any way to know for certain when a file is loaded, when it's autoload that's doing it, short of modifying the file? (I'm specifically wanting to be _notified_, so that I can prepare sub-constants to be autoloaded as well -- that is, when Foo is loaded, I want to automatically run Foo.autoload :Bar.) Is there any way to force autoload to use a different mechanism? Is there any way, in Ruby, to emulate autoload with actual feature parity? Or am I really going to have to create a temporary file for each and every source file I might possibly ever want to use?