Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re: use base 'XYZ' and exporting

by fergal (Chaplain)
on May 28, 2005 at 15:28 UTC ( [id://461357]=note: print w/replies, xml ) Need Help??


in reply to use base 'XYZ' and exporting

Won't this fail if a second module tries to use base?

You could make your own customised class which follows the conventions of "use":

use baseimp 'Foo' => ['Import', 'some', 'stuff'], 'Bar', # import defaults 'Buz' => [] # don't call import, just like use Buz () package baseimp; use base 'base'; # :) # unfortunately most modules (including base.pm) are hardwired to use +caller(0) so trickery is needed use Sub::Uplevel; sub import { my $pkg = shift; $base_import = UNIVERSAL::can(__PACKAGE__, "SUPER::import"); while (my $class = shift) { # let base do it's thing uplevel(1, $base_import, $class); # now do what use would do my $imp_args; if (ref($_[0])) { $imp_args = shift; undef $imp_args unless @$imp_args; } else { $imp_args = []; } if ($imp_args) { $class_import = UNIVERSAL::can($class, "import"); uplevel(1, $class_import, $class, @$imp_args); } } }

So without any array refs, this works exactly like base except it _does_ import stuff, when you add array refs you get to control the imports exactly as with a normal use.

Replies are listed 'Best First'.
Re^2: use base 'XYZ' and exporting
by ihb (Deacon) on May 29, 2005 at 19:16 UTC

    Your &uplevel call don't work if base is compiled before you compile Sub::Uplevel, which it is, and you can't ever guarentee to load Sub::Uplevel before base from within your module, no matter how hard you try, which is annoying. Perl needs a real uplevel().

    Anyhow, while this is a fun module, I fail to see what good it really does. I'd just stick with

    use base 'Foo'; use Foo qw/ Import some stuff /; use base 'Bar'; use Bar; use base 'Buz'; use Buz ();
    It's a few extra chars, but I and everyone else will know exactly what happens. I guess this is one of those "just because you can doesn't mean you should" situations Perl constantly provides us with. :-)

    ihb

    See perltoc if you don't know which perldoc to read!

      OK, so forget uplevel and just reimplement what base actually does. It's a pity base.pm didn't do it right from the start. If you're going to act like "use" then you should do it properly.

      As for a just a few characters, I really have a problem with that. I don't mind a few characters extra for some things but this is perfect case of when I do mind because the few characters are a repetition of information (not just, say, some extra syntax).

      That means that if I need to change the base class, I need to remember to change both occurrences. This breaks the rule of having 1 source for every piece of information and leads to subtle errors. In this case it's fairly easy to keep them in sync as they're beside each other but in another way that makes it even worse because it would be so easy to fix.

        OK, so forget uplevel and just reimplement what base actually does.

        How's that for a contradition of the spirit your main argument for using it? :-) (Having one source for every piece of information.) When base changes, it won't be a base equivalent with just an add-on.

        It's a pity base.pm didn't do it right from the start. If you're going to act like "use" then you should do it properly.

        People disagree with that "right" behaviour is, but base doesn't pretended to act like use. It can be used for any class, not just classes loaded with use. It's a module to setup inheritance at compile-time (which was important for fields).

        This breaks the rule of having 1 source for every piece of information and leads to subtle errors.

        You'll likely have to mention the class again, if you plan to use it in the code below of where you load it. (Update: Err, was about base classes, and you'll likely not name the base class again in the current package (but probably someplace else).) If you're hardcore about this, and you'll have to be if you implement a module like this and uses it, you shouldn't use hardcoded class names either. You should use $theclass = The::Class::; or something equivalent and use the variable instead, in case you need to change the class. But OAOO isn't about mentioning everything once. It's about expressing relations once. There's semantic abstraction and there's syntactic abstraction. I'm not saying that you don't agree with me on that, I'm merely clarifying. This is a both semantic and syntactic abstraction, but I'm trying to say that there is a limit on what is realistic in real life.

        In theory I agree with you. I like it the same way I like base's abstraction of loading and @ISA assignment -- I probably should've said that clearer in my reply. I like both semantic and syntactic abstraction. I'm a complete OAOO idiot. But in real life I disagree about this particular example. That's why I said "... what good it really does" (emphasis added). With this you save one occurance of the class name but you likely have at least one more occurance and already have a much harder sync problem; in comparision this is nothing and will probably be taken care of rather automatically. The cost is to confuse the maintenance people and create another hardly needed dependancy.

        If this was a patch to base or if it was a standard module it'd be another issue...

        ihb

        See perltoc if you don't know which perldoc to read!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://461357]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (5)
As of 2024-04-18 15:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found