[Pdx-pm] Austin's $VERSION trick

Michael G Schwern schwern at pobox.com
Thu Jul 14 16:30:28 PDT 2005

...didn't entirely work as written.

To recap:

The goal is to have a single location to set $VERSION for all the .pm files
in a distribution.  $VERSION has to all be on one line in order for various
CPAN utilities to spot it.

  # lib/Hello/World/Version.pm
  package Hello::World::Version;

  return 0.01;

  # lib/Hello/World.pm
  package Hello::World;

  our $VERSION = require Hello::World::Version;

This takes advantage of the fact that require returns the last evaluated
expression of the file being required (a documented but little known 

Unfortunately, this only happens the *first* time something is required.
The second time it just returns 1 since the file has already been loaded.

$ perl -Ilib -wle 'print require Hello::World::Version;  print require Hello::World::Version'

You need to either "do" the file which tells Perl to always reload it, but
you can't say "do Hello::World::Version" it has to be 
"do 'Hello/World/Version.pm'" which is kind of nasty.

But you can trick Perl into thinking that Hello::World::Version was never
loaded by deleting its entry in %INC, the record of all the .pm files that
have been loaded.

$ perl -Ilib -wle 'print require Hello::World::Version;  \
                   print keys %INC;  \
                   print require Hello::World::Version;  \
                   delete $INC{"Hello/World/Version.pm"};  \ 
                   print require Hello::World::Version'

Hello::World::Version can do this inside itself.

  package Hello::World::Version;

  delete $INC{"Hello/World/Version.pm"};

  return 0.01;

so that now "$VERSION = require Hello::World::Version" works as expected.

Michael G Schwern     schwern at pobox.com     http://www.pobox.com/~schwern
You are wicked and wrong to have broken inside and peeked at the
implementation and then relied upon it.
	-- tchrist in <31832.969261130 at chthon>

More information about the Pdx-pm-list mailing list