develooper Front page | perl.perl5.porters | Postings from March 2001

Some questions about

Tony Bowden
March 4, 2001 06:49
Some questions about
Message ID:

Yesterday I was playing around quite a bit with  I had
a lot of questions about it, but today when I checked out the latest
version (I'm still at 5.004 on my iBook) to see if there had been any
changes, I discovered Ilya's changes to move most of the core code to
Exporter::Heavy, which addressed a few of my questions, but I'm still
curious about a couple things: 

Firstly, in a couple of places there is code like this:

    *exports = *{"${pkg}::EXPORT"};
    if (@imports) {
        if (!%exports) {
            grep(s/^&//, @exports);
            @exports{@exports} = (1) x @exports;
            my $ok = \@{"${pkg}::EXPORT_OK"};
            if (@$ok) {
                grep(s/^&//, @$ok);
                @exports{@$ok} = (1) x @$ok;

This means that if I changed, for example, the inbuilt test code to look
something like:

    @EXPORT      = qw(A1 A2 A3 A4 A5);
    %EXPORT      = (Foo => 1, Bar => 1);
    @EXPORT_OK   = qw(B1 B2 B3 B4 B5);
    %EXPORT_TAGS = (T1=>[qw(A1 A2 B1 B2)], T2=>[qw(A1 A2 B3 B4)], T3=>[qw(X3)]);
    @EXPORT_FAIL = qw(B4);

that extra second line will cause the "if (!%exports)" to fail, thus never
setting up the 'correct' exports hash.

This doesn't seem to be documented behaviour, and it doesn't seem to be
particularly sensible behaviour either. Is this just a case of "Doctor,
it hurts when I do this"?, or should this change to: 
  my $exports = \@{"${pkg}::EXPORT"};
as per the EXPORT_OK below (with relevant other changes, of course),
and lose the "if (!%exports)" check? 

Also, if much of the plan here for Exporter was to reduce the memory
consumption, should we not standardise which method of dealing with the
leading & issue is used? The current code contains both idioms:

  # Build cache of symbols. Optimise the lookup by adding
  # barewords twice... both with and without a leading &.
  # (Technique could be applied to %exports cache at cost of memory)
  my @expanded = map { /^\w/ ? ($_, '&'.$_) : $_ } @fail;
  grep(s/^&//, @$ok);

I'm not sure either is best - if we're trying to save memory, then the
second is probably better, but we should probably lose the grep in a
void context.

Thirdly, the require version code seems a little weird. It's not a big
deal, but theoretically you could write:
  use Foo 1.23 1.22 1.24 1.21 1.11;
which would "work", but seems strange.

The code currently says: foreach symbol we want to import, that hasn't
been declared as a valid export, see if it's a version. If it's not,
then throw a "not exported" problem, else make sure we have that version,
then break if there's only 1 or 2 symbols to check. The "multiple version"
issue just falls through the cracks. I'm not sure it's worth doing much
about though - perhaps remove it from @imports so that at the final case
you'll still be able to do:
  use Foo 1.23 1.22 1.24 1.21 1.11 '';
which you can't at the moment?

Actually, when I said above that it checks "if it's a version", that isn't
really true either - it just checks if the symbol starts with a digit: 
  if ($sym =~ m/^\d/) { $pkg->require_version($sym); 
which may not be the best idea either, as it generally gets thrown
into a numeric comparison. Is it worth making sure that someone doesn't
   use Foo '3.F';
for example?

I'd also be interested in people's opinions on expanding the behaviour
of require_version slightly, so that rather than only being able to say
you want anything at version 1.23 or above, that you want something at
exactly 1.23, or no higher than 1.23. Sometimes modules do upgrade in
a non-backwards-compatible way, or in a way that means you need to
change something to use them ( is a prime example), and it would
be useful to be able to say: only load it if it's *before* version
2.64. (Enabling it to check multiple versions until it gets the one it
wants would then be useful too, but that could come later!) I'm not
sure what the syntax should be like though.


 Tony Bowden | |
       may my mind stroll about hungry and fearless and thirsty and supple    
-------------------------------------------------------------------------- Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About