Need advice- would like to implement a delayed-load proxy class

I’d like to have const_missing return a class that would do the
following:

  1. Have the same class name as the class it should have loaded but
    without loading the class. Let’s call this “proxy”.

That part is easy, as I’ve done similar in my constance gem. Here is
where it starts to get more difficult:

  1. Implement method missing such that when “proxy” is called it in turn
    calls another class that unloads the proxy class and then loads the
    originally requested file.

Implementing method missing is easy, and removing a constant not hard
either, but how can an unloaded class return something from method
missing when it is gone? That wouldn’t work.

So then you might say “of course not, just use method missing and return
from the proxy”, but if possible I don’t want to have the “proxy” class
act as a wrapper or delegate all calls because that is additional
overhead. Maybe it would be ok and transparent and I could mess with the
caller stack to make it appear as if the proxy were not even there, but
I think eventually the magic go-between wrapper would be a problem.

This actually isn’t an academic question- I was trying to think of a
solution to the problem of people using names of classes rather than the
constants in class bodies where associations, etc. are defined in Rails
(note: this is not a Rails question, but yes that is where I’d like to
use it). By returning a flyweight proxy class that loads and calls the
real class as needed, they wouldn’t need to use strings instead of
classnames because const_missing would return something that didn’t get
into some sort of massive autoloading disaster that the community is
afraid of.

Sorry if this just sounds idiotic.

Ha! Oops, wrong order, I meant:

def method_missing(meth, *args, &block)
# really load class or get instance, and then call method on it
c = SomeAutoloader.get(@@name).send(meth, *args, &block)
remove_class_variable(:@@name)
c
end

class FlyweightProxy < BasicObject

Flyweight is a misnomer since is not implementing flyweight pattern.
LazyLoadingProxy may be a better name.

That part is easy, as I’ve done similar in my constance gem.

Sorry, I meant the classmeta gem:

Been thinking more about this, and although I still think it is a
somewhat horrid idea, I thought of some tweaks:

class FlyweightProxy < BasicObject
def initialize(const_name)
@@name = const_name
end

def method_missing(meth, *args, &block)
remove_class_variable(:@@name)
# really load class or get instance, and then call method on it
SomeAutoloader.get(@@name).send(meth, *args, &block)
end
end

this is not to be taken literally. for example, in classmeta I

overrode the method called in Rails autoloading via alias_method’ing and
redefining load_missing_constant, which I might have just been able to
do via defining load_missing_constant and calling super instead, but
don’t remember if I tried that:

module ModuleConstMissing
def const_missing(const_name)
FlyweightProxy.new(const_name)
end
end

Module.class_eval { include ModuleConstMissing }

But, I’m not sure if that would work (need to test).

Sorry if this is way too poorly thought out. Just looking for ideas,
mostly.

Gary W. wrote in post #1086999:

I’d like to have const_missing return a class that would do the
following:

  1. Have the same class name as the class it should have loaded but
    without loading the class. Let’s call this “proxy”.

That part is easy, as I’ve done similar in my constance gem. Here is
where it starts to get more difficult:

  1. Implement method missing such that when “proxy” is called it in turn
    calls another class that unloads the proxy class and then loads the
    originally requested file.

Implementing method missing is easy, and removing a constant not hard
either, but how can an unloaded class return something from method
missing when it is gone? That wouldn’t work.

So then you might say “of course not, just use method missing and return
from the proxy”, but if possible I don’t want to have the “proxy” class
act as a wrapper or delegate all calls because that is additional
overhead. Maybe it would be ok and transparent and I could mess with the
caller stack to make it appear as if the proxy were not even there, but
I think eventually the magic go-between wrapper would be a problem.

This actually isn’t an academic question- I was trying to think of a
solution to the problem of people using names of classes rather than the
constants in class bodies where associations, etc. are defined in Rails
(note: this is not a Rails question, but yes that is where I’d like to
use it). By returning a flyweight proxy class that loads and calls the
real class as needed, they wouldn’t need to use strings instead of
classnames because const_missing would return something that didn’t get
into some sort of massive autoloading disaster that the community is
afraid of.

Sorry if this just sounds idiotic.