A question came up here recently where a user wished to specify a minimum version for a parent class. base doesn't support specifying minimum versions, nor does parent. base and parent are core Perl modules. I don't think it would be appropriate to add complexity to the core Perl parent by adding this feature.

Perl facilitates setting minimum versions in use statements:

use Time::HiRes 1.9;

use has a compiletime effect, so that code behaves like this:

BEGIN { require Time::HiRes; Time::HiRes->VERSION(1.9) Time::HiRes->import }

However, BEGIN blocks require us to consider the order of loading more than we may want to. This doesn't fit the model of keeping simple things simple, if the simple thing we want to do is fairly common.

For inheritance we can do this:

package MyAgent; BEGIN { require LWP::Usergent; LWP::UserAgent->VERSION(6.39); # Assert a minimal version. push @MyAgent::ISA, 'LWP::UserAgent'; }

To me that's too much boilerplate for a common need. Another way:

package MyAgent; use parent 'LWP::UserAgent'; BEGIN {LWP::UserAgent->VERSION(6.39)}

But that's a little fragile; someone may refactor and forget to keep the BEGIN block after the call to parent causing things blow up. Sometimes code becomes complex, masking simple mistakes. I would prefer a solution that doesn't require the user to maintain several steps to set up inheritance while assuring minimal versions for parent classes.

parent::versioned makes the inheritance and compile-time version checking more convenient, and harder to get wrong. I uploaded it to CPAN a few hours ago.

package Myagent; use parent::versioned ['LWP::UserAgent' => 6.39];

parent and parent::versioned behave the same for all import lists unless an element in the import list is an array ref. Any array ref passed to the import list will be treated as a tuple that specifies a module name, and a minimum version for that module. Multiple inheritance works like this:

use parent::versioned ['LWP::UserAgent' => 6.39], ['Mojo::DOM' => 7.2 ], 'Foo::Base';

This example sets up triple inheritance: two modules that are version checked, and one that is not. As with parent, parent::versioned accepts the -norequire flag.

The parent module has 100% code test coverage. parent::versioned passes the parent test suite and maintains 100% coverage. It should work as a drop-in replacement for parent, but with the additional functionality exposed by passing an array-ref as part (or all) of the import list. Most of the code is a direct fork from parent. You can use it just like you use parent:

use parent::versioned qw(Foo);

I prefer keeping the module small, but if you're interested please do look at the GitHub repository. Patches, issues, and suggestions are welcomed. I hope it becomes useful.


Dave


In reply to parent::versioned supports minimum version specification in parent classes by davido

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.