nothingmuch has asked for the wisdom of the Perl Monks concerning the following question:

I was wondering (yes, i know i should stop).
Using perl you can do pretty much anything you were supposed to do in compile time at run time intead, right?
How's about dynamically creating namespaces?

I need an object to inherit different classes, at different times.

The object has some data, which can be passed to a 'reblesser' function, which dynamically selects where the object can go now, and if it's allowed there, and if there are several such methods which one, based on info within the object.

I thought of something with eval, or perhaps modifying %::, but i don't know how this really worked.

Another idea is using AUTOLOADER to trancend the object on demand when it needs, calling rebless when a method isn't found.
This will REALLY hurt method call times, which are slow to start with.

Which of the two methods is preferable? Do they work? How do i get around perl caching methods found in @ISA?

i haven't found much documentation, and experimenting seems to always go wrong for me, so i was hoping someone's tried this before...

-nuffin
zz zZ Z Z #!perl
  • Comment on Dynamicly controlling @ISA and namespaces

Replies are listed 'Best First'.
•Re: Dynamicly controlling @ISA and namespaces
by merlyn (Sage) on Mar 27, 2003 at 20:14 UTC
Re: Dynamicly controlling @ISA and namespaces
by dragonchild (Archbishop) on Mar 27, 2003 at 20:16 UTC
    Another option is to have a factory and just rebless. Or, use various design patterns. One that might be useful is the Veneer.

    Explanation:

    Another option is to use a Factory class. This is a design pattern that is explained in the book Design Patterns by the Gang of Four. (You can find it at www.amazon.com or any large bookstore. Most large libraries also have a few copies laying around.) The basic principle is to have an object that will create objects for you, given some set of information.

    The reason why this is useful is that you encapsulate most, if not all, of the class information. The code using these objects only need to know that they need a Porsche or a Boeing747, not that they need a Vehicle::Car::Porsche or a Vehicle::Air::Boeing747. Now, the usefulness of this pattern for you is that you can have your reblessing logic hidden within this Factory class.

    Design Patterns contains a number of other ideas that may be useful here. One is the Veneer. (It's got other names, but that's the one I remember.) The idea is that you have some object - call it a Window. Now, you might have some Windows with borders and some Windows without borders.

    One way to solve this problem is to create a Window class and a BorderWindow class. Not a big deal. Another solution is to have the Window class know how to handle borders. Again, not a big deal.

    What if you have 10 options instead of just 1? That's over 1000 classes or a large set of if-else statements, just to deal with one change in how the object is displayed on the screen.

    So, what you do is create your Window class and you also create a Border class. The Border class is very small and handles all methods the Window class does. All has is a reference to the Window class and maybe a few attributes for itself. It delegates all calls back to the Window class, except for the Paint() method, which it does a few things, then delegates.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Re: Dynamicly controlling @ISA and namespaces
by djantzen (Priest) on Mar 27, 2003 at 20:30 UTC
Re: Dynamicly controlling @ISA and namespaces
by traveler (Parson) on Mar 27, 2003 at 21:06 UTC
@ISA patterns dynamic inheritance evil decorator
by Anonymous Monk on Mar 30, 2003 at 04:52 UTC
    NoSexUntilMarriage on the slowass wiki has more than a few things to say about this, some of them covered here. There are a lot of reasons not to do what you're proposing. You usually want to affect one instance of a class, not the entire class. If you want to affect the entire class, fine, as already said, just use some indirection to hide the implementation. You probably really want one of: StatePattern - implementation dependent upon state, DecoratorPattern - composition through chains of delegation, InnerClasses - writing little built-in adapters to expose alternate interfaces to objects, Or, as mentioned, Class::Classless, which lots you use existing objects as prototypes for new objects. JavaScript works this way, for anyone who has actually played with the OO elements of JavaScript. Interesting, thats all. Yes, this like all of my posts is a shameless plug. Flame on. -scrottie