in reply to VERSION format & compare
This might be of interest:
Foo->VERSION(...) | Foo->import(...) | |
---|---|---|
use Foo | - | () |
use Foo () | - | - |
use Foo 'list' | - | ('list') |
use Foo 1.23 | ('1.23') | () |
use Foo 1.23 () | ('1.23') | - |
use Foo 1.23 'list' | ('1.23') | ('list') |
use Foo 1.23, 'list' | - | ('1.23','list') |
use Foo 1.23 , 'list' | syntax error | |
use Foo '1.23' | - | ('1.23') |
use Foo 1.2.3 | (1.2.3) | () |
use Foo 1.2.3 () | (1.2.3) | - |
use Foo 1.2.3 'list' | (1.2.3) | ('list') |
use Foo 1.2.3, 'list' | - | (1.2.3,'list') |
use Foo 1.2.3 , 'list' | syntax error | |
use Foo '1.2.3' | - | ('1.2.3') |
use Foo '1.2.3' () | syntax error | |
use Foo '1.2.3' 'list' | syntax error | |
use Foo '1.2.3', 'list' | - | ('1.2.3','list') |
use Foo '1.2.3' , 'list' | - | ('1.2.3','list') |
Note that (1.2.3) is a list of one v-string, as opposed to ('1.2.3'), a list of one regular string. Also, I was a bit surprised myself about use Foo 1.23, 'list' vs. use Foo 1.23 , 'list' (with the space before the comma) throwing an error as I hadn't encountered that case so far, but I guess it goes to show that use gets special parsing by Perl.
Code used to generate the table follows:
#!/usr/bin/env perl use warnings; use strict; use Data::Dumper; use HTML::Tiny; sub dmp { Data::Dumper->new([\@_])->Terse(1)->Indent(0)->Dump =~ s/\A\s*\[(.*)\]\s*\z/($1)/sr } our ($version,$import); sub Foo::VERSION { shift eq 'Foo' or die; $version = &dmp } sub Foo::import { shift eq 'Foo' or die; $import = &dmp } $::INC{'Foo.pm'} = $0; my $h = HTML::Tiny->new; my @rows = ( [ \'th', ' ', $h->tt($h->entity_encode('Foo->VERSION(...)')), $h->tt($h->entity_encode('Foo->import(...)' )), ] ); while ( my $code = <DATA> ) { chomp($code); ($version,$import) = (undef)x2; my $error = eval "no warnings; $code; 1" ? undef : $@; $error =~ s/\s+at\s+\(?eval\b.+\z//s if defined $error; if (defined $error) { push @rows, [ $h->td( $h->tt($h->entity_encode($code )), {colspan=>2}, $h->i($h->tt($h->entity_encode($error ))) ) +]; } else { push @rows, [ \'td', $h->tt($h->entity_encode($code )), defined $version ? $h->tt($h->entity_encode($version)) : ' +-', defined $import ? $h->tt($h->entity_encode($import )) : ' +-' ]; } } print $h->html( [ $h->head( $h->title( 'use' ) ), $h->body( [ $h->table({border=>1,cellspacing=>0}, [ \'tr', @rows ]), ] ) ] ); __DATA__ use Foo use Foo () use Foo 'list' use Foo 1.23 use Foo 1.23 () use Foo 1.23 'list' use Foo 1.23, 'list' use Foo 1.23 , 'list' use Foo '1.23' use Foo 1.2.3 use Foo 1.2.3 () use Foo 1.2.3 'list' use Foo 1.2.3, 'list' use Foo 1.2.3 , 'list' use Foo '1.2.3' use Foo '1.2.3' () use Foo '1.2.3' 'list' use Foo '1.2.3', 'list' use Foo '1.2.3' , 'list'
Update: For the sake of completeness, use Module VERSION LIST (where both VERSION and LIST are optional) is equivalent to:
BEGIN { require Module; Module->VERSION( VERSION ); # if VERSION was specified Module->import( LIST ); # *except* when LIST is "()" }
And use VERSION; requires a minimum version of Perl, enables the feature bundle for that version and strict if the version is 5.12 or greater. Also, if Module doesn't have a sub import, no error is raised. All packages inherit a method VERSION from UNIVERSAL, which apparently is defined in terms of version (a core module as of Perl 5.10, although I can't seem to find it on perldoc.perl.org, which I assume is a bug there).