Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

schwern (1528)

schwern
  (email not shown publicly)
http://schwern.net/
AOL IM: MichaelSchwern (Add Buddy, Send Message)
Jabber: schwern@gmail.com

Schwern can destroy CPAN at his whim.

Journal of schwern (1528)

Tuesday July 31, 2007
06:10 AM

What's all the fuss about base.pm?

[ #33927 ]

This post on p5p is worth repeating:

Johan Vromans wrote:
>>From Ricardo SIGNES > Perl-Critic-Tics-0.002 >
> Perl::Critic::Policy::Tics::ProhibitUseBase :
>
> "use base qw(Baseclass);
>
> You've seen that a hundred times, right? That doesn't mean that
> it's a good idea. It screws with $VERSION, it (temporarily)
> clobbers your $SIG{__DIE__}, it doesn't let you call the base
> class's import method, it pushes to @INC rather than replacing it,
> and it devotes much of its code to handling the nearly totally
> unused fields pragma -- but the multiple inheritence that pushing
> to @INC sets up is not supported by fields."
>
> Is this still true? I thought most of these issues were dealt with.

If they aren't, nobody's reported them.

* The $SIG{__DIE__} issue is fixed.
* I don't know what people are talking about screwing with $VERSION.
* You shouldn't be importing functions from a superclass and nobody's
    stopping you from adding a "use Baseclass" if you really want to.
* I've yet to see a practical reason why pushing to @INC is wrong.
    If it replaced @INC the same people would be complaining I'm sure.
* Who cares how much code it devotes to fields?
* Who cares if fields doesn't support MI? Does anyone use fields anymore?

Most folks miss the important points:
* It happens at compile time.
* It has error checking.

That its at compile time avoids some nasty circular dependency issues such as...


# File A.pm
package A;

use B;
@ISA = qw(B);

use C;

1;

# File B.pm
package B;

sub foo { 42 }

1;

# File C.pm
package C;

print A->isa("B") ? "Yes\n" : "No\n";
print A->can("foo") ? "Yes\n" : "No\n";

1;

Use base instead and that all works. Yes, C should be using A but I've read a lot of commercial code that just assumes other modules are loaded and its a horrible thing to debug.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • * You shouldn't be importing functions from a superclass and nobody's stopping you from adding a "use Baseclass" if you really want to.

    True, but it's frustrating to inherit from a base class which might need arguments passed to its import method. There was some discussion about this on P5P and I recall someone suggesting something like this:

    use base
      'SomeClass',
      'SomeOtherClass' => { import => [ qw/import args/ ] };

    That would be backwards compatible and get around that limitation

    • Also import() isn't just used to, umm, import. It's quite a common idiom to use it to pass global settings to a class, such as telling it to put temporary files in a particular place, or changing its default timezone. Those still have their place in OO programming.

      Even so, I don't consider this to be a problem with base.pm. If I really need to do things like that, the work-around is trivial.

    • Here's what I expressed on p5p: 80% of the code and syntax will be devoted to a feature that you use 1% of the time and has a perfectly reasonable work around that everyone understands. Just not worth the extra work/complexity/documentation/bugs.


              use base qw(Foo);
              use Foo qw(some args);


      And isn't it "let's add just one more feature" that got base.pm in this situation in the first place?
  • * I don't know what people are talking about screwing with $VERSION.

    Not that I think it's a problem - but I think folk are referring to base setting VERSION to '-1, set by base.pm' if it's undef.

    Adrian (thoroughly in the "liking base" camp)

  • The policy in question comes from Perl-Critic-Tics, which describes itself as: The Perl-Critic-Tics distribution includes extra policies for Perl::Critic to address a fairly random assortment of things that make me (rjbs) wince.

    In other words: it's things that I don't want to see in my code. If you want to be like me, swell.

    I don't think any of the things I listed are *bugs*, they're just things that *I don't like*.

    "You shouldn't be importing functions from a superclass." Wishing doesn't make it so. In
    --
    rjbs
  • Yes, C should be using A but I've read a lot of commercial code that just assumes other modules are loaded and its a horrible thing to debug.

    What a bogus argument. I would accept this if you had said "I have written a lot of commercial code that just assumes ...", but arguing a (unremovable, by now) misfeature of your code as something actually beneficial is quite a stretch. I hadn't looked at the source code of base.pm before people argued against it, but for my taste it is far too close to the code of

    • I think we're having a violent agreement. My example about the commercial code was illustrating the importance of inheriting at compile time vs setting @ISA at run time. All the other details of "use base" are orthogonal.

      Some people remember to put a BEGIN around setting @ISA (and @EXPORT) but most don't either because they forget or aren't aware.