Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

package Foo; isa Bar; why not?

by liz (Monsignor)
on Dec 18, 2003 at 23:44 UTC ( #315694=perlmeditation: print w/ replies, xml ) Need Help??

I like Bart's Re: It's one of the reasons I wrote vars::i idea for an isa.pm so much, that I worked a bit more on it. The only thing I have against it, is that you would need to say "use isa qw(Bar)". It should be possible to do this shorter. Something like:
require isa; # this should go away once this is in the core package Foo; isa Bar;
I came up with the following (temporary) implementation:
package isa; use strict; use warnings; BEGIN { no warnings 'redefine'; my $old = \&UNIVERSAL::isa; *UNIVERSAL::isa = sub { goto &$old if defined wantarray; no strict 'refs'; push @{caller().'::ISA'}, @_; } #UNIVERSAL::isa } 1;
The code depends on giving another meaning of the UNIVERSAL::isa subroutine, namely when it is being called in void context: in that case it will set the caller's @ISA array with the parameters passed.

I like the syntax this gives. It has its limitations though, as you can list only one inheritance at a time. That's because the syntax of:

isa Bar;
actually is the indirect object syntax for:
Bar->isa;

I wonder what other Monks think of this: is it a good idea? or is it an abomination? To me, it is one of the first "natural" uses of indirect object syntax.

Liz

Comment on package Foo; isa Bar; why not?
Select or Download Code
Re: package Foo; isa Bar; why not?
by chromatic (Archbishop) on Dec 19, 2003 at 00:34 UTC

    Aside from slightly different syntax, why should this go in the core when base is already there and already does the same thing and more?

      It's the and more thing I don't like about base.pm. If you just need base.pm for setting @ISA at compile time, it's a lot of baggage that you're schlepping along.

      And on the other hand, base.pm is not doing enough: if you need a module's import method called, you still need to either use the module with the right parameters before calling base.pm, or you need to call the import yourself afterwards.

      So yes, I don't like base.pm.

      Liz

Re: package Foo; isa Bar; why not?
by !1 (Hermit) on Dec 19, 2003 at 01:10 UTC

    Any chance of a require? I do like it over use base even if the only thing changing between the two is that you can say isa Bar instead of use base "Bar". There is one slight catch, though:

    #!/usr/bin/perl -wl our @ISA; use isa; isa Foo,Bar; # drops Bar and also spits out warning... # works same if you quote Bar, dies if Foo # is quoted or we're under strict print "@ISA"; @ISA = (); Foo->isa("Bar"); # this works but the syntax is...funky print "@ISA"; @ISA = (); UNIVERSAL::isa(qw(Foo Bar)); # kinda long, eh? print "@ISA"; @ISA = (); main->isa(qw(Foo Bar)); # makes sense... pushes itself onto # @ISA, though __END__ Useless use of a constant in void context at isa.pl line 5. Foo Foo Bar Foo Bar main Foo Bar

    It doesn't do the right thing if you'd like to declare it for more than one package at a time. With base you can do as many as you want. The only ways I can think of fixing it is to actually export a version to the package that's using isa's functionality. I dunno. Works great for one package but otherwise doesn't seem to be as clean of a solution as it could be.

      isa Foo,Bar; # drops Bar and also spits out warning...
                   # works same if you quote Bar, dies if Foo
                   # is quoted or we're under strict
      
      That's because it is using indirect object syntax.

      Note that you can say:

      isa Bar qw(Baz Bas Boo);
      which is not so nice as there is no way to explain why "Bar" should be specified differently from "Baz", "Bas" and "Boo". Maybe a more consistent way of specifying multiple inheritance would be:
      isa Bar, isa Baz, isa Bas, isa Boo;

      main->isa(qw(Foo Bar)); # makes sense... pushes itself onto
                              # @ISA, though
      This can be easily fixed in isa.pm:
      -push @{caller().'::ISA'}, @_; +push @{caller().'::ISA'}, map {m#^main$# ? () : $_} @_;

      ... doesn't seem to be as clean of a solution as it could be.

      I agree. I think I'll go back to just setting @ISA myself, and making sure they're run at compile time when I put several packages into one file.

      Liz

        This isn't meant as a criticism, however, why use map in place of grep?

        my $caller = caller(); push @{"$caller\::ISA"}, grep $_ ne $caller, @_;

        I do use map with the empty return quite often when a list/array requires filtering and transformation because it tends to make me feel warm and fuzzy inside. Multiple maps and greps can become confusing. However, if all you're doing is filtering then grep to be clearer (and I believe faster, too).

Re: package Foo; isa Bar; why not?
by pg (Canon) on Dec 19, 2003 at 03:32 UTC

    I see this as a bad idea.

    Perl's OO is heavily hacked, but the best way to improve it and make it less hacked, is to improve it from inside out and bottom up, not to hack more.

    Before it gets resolved in the core, the best solution is to live with it. In fact, although Perl's OO is not perfect, lots of people use Perl OO and even love it, and lots of the core modules have OO style.

    To hack more does not improve anything.

Re: package Foo; isa Bar; why not?
by Anonymous Monk on Dec 19, 2003 at 06:14 UTC

    What is the point to post two meditations in a day on the same topic? This is not fun at all. You should have gotten organized before you throw it out.

    At the same time, do you think the quality of this post really worth a meditation, not a SOPW?

      I disagree with liz's idea but think it was worth bringing up. More people should write and share code when they have ideas.

Re: package Foo; isa Bar; why not?
by ysth (Canon) on Dec 19, 2003 at 07:29 UTC
    @ISA really ought to be set at compile time. Is there something you have against use base?
Re: package Foo; isa Bar; why not?
by Anonymous Monk on Dec 19, 2003 at 07:44 UTC
    # this should go away once this is in the core

    Are you so sure that it should go in the core?

    No doubts at all? A tiny, weeny, little doubt?

    No? Then let the new pragma be.

    Or maybe not? Maybe someone from the unwashed has doubts?

Re: package Foo; isa Bar; why not?
by Abigail-II (Bishop) on Dec 19, 2003 at 09:43 UTC
    I wonder what other Monks think of this: is it a good idea?
    I think the package offers little - it just replaces a one line idiom with a one line idiom. Therefore, I don't think it should be in the core.

    Put it on CPAN. If it turns out to be popular, you could always start a lobby to get it in the core.

    Abigail

Re: package Foo; isa Bar; why not?
by Anonymous Monk on Dec 19, 2003 at 10:04 UTC
    Yuck. I don't think this should be in use, much less in core (sorry).
    To me, it is one of the first "natural" uses of indirect object syntax.
    IMHO, there is only one use for indirect object syntaxt, and it is poetry
    The only thing I have against it, is that you would need to say "use isa qw(Bar)". It should be possible to do this shorter.
    It's too late. As a core language feature, maybe, but it's too late for that. But by way of yucky yucky yuck yuck and not during compiletime? No.
Re: package Foo; isa Bar; why not?
by BrowserUk (Pope) on Dec 19, 2003 at 10:26 UTC

    FWIW, if it weren't for the syntactic/parser limitations that go with indirect object syntax, there have been several situations were I would have liked to have used it. I'm kinda hoping that the P6 syntax definitions will be more precise, and will subsequently allow it's use safely, assuming that it will still be there after Apo-12.

    For your isa module, it seems almost too trivial as it is to be worth making it a module. However, I think that your right about use base;, and there are various other OO utility modules around that provide some things which are useful and bits which I think are redundant. It would be nice to sort out a set of useful, lightweight, general purpose extensions to the standard perl OO and put them together, as a single pragma.

    It would probably be best if it was possible to get a collective opinion on what people would like to see (that is practical and simple and lightweight) to "clean-up" the current unenhanced state of P5's OO.

    There are already a large number of OO enhancement modules on CPAN, but they overlap a lot, each has some good bits and some bad bits. Many of them cannot be used together because of design, implementation or methodology conflicts.

    In the same way that there was a project to clean up, simplify and coalese the various Date and Time modules kicking around that resulted in DateTime. A similar project would be beneficial to the whole arena of perl's OO -- I think.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    Hooray!

Re: package Foo; isa Bar; why not?
by demerphq (Chancellor) on Dec 19, 2003 at 17:43 UTC

    Hi Liz. Im a little confused why a simple

    package Foo; BEGIN { @ISA=qw( blah blah blah ); }

    Doesnt cut it in your eye. For me the capitalization, the BEGIN, etc, all make this a much more potent way to write this. Its immediately obvious that "theres some voodoo going on" and what that voodoo is. Your isa approach doesnt tickle my fancy im afraid.

    I will say that I agree with your issues with use base. I pretty much dont use it anymore, as I've found there are bizarre situations where it doesnt do what you might expect.

    Actually on a less serious level, a module like:

    package CompileTime; 1

    Which could then be used like:

    use CompileTime @ISA=qw(blah blah blah);

    Which I guess is just a fancy BEGIN without the squiggle brackets. :-)


    ---
    demerphq

      First they ignore you, then they laugh at you, then they fight you, then you win.
      -- Gandhi


Re: package Foo; isa Bar; why not?
by Kageneko (Scribe) on Dec 22, 2003 at 18:51 UTC

    Here's a variation I came up with using Filter::Simple:

    package Filter::ISA; use Filter::Simple; FILTER_ONLY code => sub { if ( /package\s+(.+?)\s+isa\s+(.+?);/g ) { my $name = $1; my $base = $2; if ( $name !~ /;/ ) { $base =~ s/,/ /go; s/package $name isa (.+);/package $name; use base qw( $base );/o +; } } }; 1;

    It lets one do things like:

    package A isa B; package D isa E,F;

    I'm kinda tempted to post it to CPAN now, but I imagine there's a lot better stuff out there :)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://315694]
Front-paged by broquaint
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (6)
As of 2014-08-23 08:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (172 votes), past polls