develooper Front page | perl.perl6.language | Postings from February 2003

use only The::Finest => 1.23;

From:
Brian Ingerson
Date:
February 19, 2003 12:18
Subject:
use only The::Finest => 1.23;
Message ID:
20030218223926.C32301@ttul.org
I've just released a module called 'only.pm' that allows people to
install multiple versions of various modules. It also lets them 'use'
specific versions.

It was suggested to me that this might contribute insight towards module
versioning in Perl6. Have fun.

Here is the doc:

  NAME
      only - Load specific module versions; Install many
  
  SYNOPSIS
          # Install version 0.30 of MyModule
          cd MyModule-0.30
          perl Makefile.PL
          make test
          perl -Monly=install    # substitute for 'make install' 
      
          # Only use MyModule version 0.30
          use only MyModule => '0.30';
  
          # Only use MyModule if version is between 0.30 and 0.50
          # but not 0.36; or if version is >= to 0.55.
          use only MyModule => '0.30-0.50 !0.36 0.55-', qw(:all);
  
          # Don't export anything!
          use only MyModule => '0.30', [];
  
          # Version dependent arguments
          use only MyModule =>
              [ '0.20-0.27', qw(f1 f2 f3 f4) ],
              [ '0.30-',     qw(:all) ];
  
  USAGE
          # Note: <angle brackets> mean "optional".
  
          # To load a specific module
          use only MODULE => 'CONDITION SPEC' <, ARGUMENTS>;
  
          # For multiple argument sets
          use only MODULE => 
              ['CONDITION SPEC 1' <, ARGUMENTS1>],
              ['CONDITION SPEC 2' <, ARGUMENTS2>],
              ...
              ;
  
          # To install an alternate version of a module
          perl -Monly=install <- VERSION>        # instead of 'make install'
  
  DESCRIPTION
      The "only.pm" facility allows you to load a MODULE only if it satisfies
      a given CONDITION. Normally that condition is a version. If you just
      specify a single version, 'only' will only load the module matching that
      version. If you specify multiple versions, the module can be any of
      those versions. See below for all the different conditions you can use
      with "only".
  
      "only.pm" will also allow you to load a particular version of a module,
      when many versions of the same module are installed. See below for
      instructions on how to easily install many different versions of the
      same module.
  
  CONDITION SPECS
      A condition specification is a single string containing a list of zero
      or more conditions. The list of conditions is separated by spaces. Each
      condition can take one of the following forms:
  
      * plain version
          This is the most basic form. The loaded module must match this
          version string or be loaded from a version directory that uses the
          version string. Mulitiple versions means one or the other.
  
              use only MyModule => '0.11';
              use only MyModule => '0.11 0.15';
  
      * version range
          This is two single versions separated by a dash. The end points are
          inclusive in the range. If either end of the range is ommitted, then
          the range is open ended on that side.
  
              use only MyModule => '0.11-0.12';
              use only MyModule => '0.13-';
              use only MyModule => '-0.10';
              use only MyModule => '-';       # Means any version
  
          Note that a completely open range (any version) is not the same as
          just saying:
  
              use MyModule;
  
          because the "only" module will search all the various version libs
          before searhing in the regular @INC paths.
  
          Also note that an empty string or no string means the same thing as
          '-'.
  
              # All of these mean "use any version"
              use only MyModule => '-';
              use only MyModule => '';
              use only 'MyModule';
  
      * complement version or range
          Any version or range beginning with a '!' is considered to mean the
          inverse of that specification. A complement takes precedence over
          all other specifications. If a module version matches a complement,
          that version is immediately rejected without further inspection.
  
              use only MyModule => '!0.31';
              use only MyModule => '0.30-0.40 !0.31-0.33';
  
      The search works by searching the version-lib directories (found in
      "only::config") for a module that meets the condition specification. If
      more than one version is found, the highest version is used. If no
      module meets the specification, then a normal @INC style "require" is
      performed.
  
      If the condition is a subroutine reference, that subroutine will be
      called and passed an "only" object. If the subroutine returns a false
      value, the program will die. See below for a list of public methods that
      may be used upon the "only" object.
  
  ARGUMENTS
      All of the arguments following the CONDITION specification, will be
      passed to the module being loaded.
  
      Normally you can pass an empty list to "use" to turn off Exporting. To
      do this with "only", use an empty array ref.
  
          use only MyModule => '0.30';       # Default exporting
          use only MyModule => '0.30', [];   # No exporting
          use only MyModule => '0.30', qw(export list);  # Specific export
  
      If you need pass different arguments depending on which version is used,
      simply wrap each condition spec and arguments with an array ref.
  
          use only MyModule =>
              [ '0.20-0.27', qw(f1 f2 f3 f4) ],
              [ '0.30-',     qw(:all) ];
  
  INSTALLING MULTIPLE MODULE VERSIONS
      The "only.pm" module also has a facility for installing more than one
      version of a particular module. Using this facility you can install an
      older version of a module and use it with the 'use only' syntax.
  
      It works like this; when installing a module, do the familiar:
  
          perl Makefile.PL
          make
          make test
  
      But instead of "make install", do this:
  
          perl -Monly=install
  
      This will attempt to determine what version the module should be
      installed under. In some cases you may need to specify the version
      yourself. Do the following:
  
          perl -Monly=install - 0.55
  
      NOTE: Also works with "Module::Build" style modules.
  
      NOTE: The "perl" you use for this must be the same "perl" as the one
      used to do "perl Makefile.PL" or "perl Build.PL". While this seems
      obvious, you may run into problems with "sudo perl -Monly=install",
      since the "root" account may have a different "perl" in its path. If
      this happens, just use the full path to your "perl".
  
  INSTALLATION LOCATION
      When you install the "only" module, you can tell it where to install
      alternate versions of modules. These paths get stored into
      "only::config". The default location to install things is parallel to
      your sitelib. For instance if your sitelib was:
  
          /usr/lib/perl5/site_perl
  
      "only" would default to:
  
          /usr/lib/perl5/version
  
      This keeps your normal install trees free from any potential
      complication with version modules.
  
      If you install version 0.24 and 0.26 of MyModule and version 0.26 of
      Your::Module, they will end up here:
  
          /usr/lib/perl5/version/0.24/My/Module.pm
          /usr/lib/perl5/version/0.26/My/Module.pm
          /usr/lib/perl5/version/0.26/Your/Module.pm
  
  HOW IT WORKS
      "only.pm" is kind of like "lib.pm" on Koolaid! Instead of adding a
      search path to @INC, it adds a search object to @INC. This object is
      actually the "only.pm" object itself. The object keeps track of all of
      the modules related to a given package installation, and takes
      responsibility for loading those modules. This is very important because
      if you say:
  
          use only Goodness => '0.23';
  
      and then later:
  
          require Goodness::Gracious;
  
      you want to be sure that the correct version of the second module gets
      loaded. Especially when another module is doing the loading.
  
  THE FINE PRINT ON VERSIONING
      The "only.pm" module loads a module by the following process:
  
       1) Look for the highest suitable version of the module in the version
          libraries specified in only::config.
   
       else:
   
       2) Do a normal require() of the module, and check to make sure the 
          version is in the range specified.
  
      It is important to understand that the versions used in these two
      different steps come from different places and might not be the same.
  
      In the first step the version used is the version of the "distribution"
      that the module was installed from. This is grepped out of the Makefile
      and saved as metadata for that module.
  
      In the second step, the version is taken from $VERSION of that module.
      This is the same process used when you do something like:
  
           use MyModule '0.50';
  
      Unfortunately, there is no way to know what the distribution version is
      for a normally installed module.
  
      Fortunately, $VERSION is usually the same as the distribution version.
      That's because the popular "VERSION_FROM" Makefile.PL option makes it
      happen. Authors are encouraged to use this option.
  
      The conclusion here is that "only.pm" usually gets things right. Always
      check %INC, if you suspect that the wrong versions are being pulled in.
      If this happens, use more 'use only' statements to pull in the right
      versions.
  
      One failsafe solution is to make sure that all module versions in
      question are installed into the version libraries.
  
  LOADING MULTIPLE MODULE VERSIONS (at the same time)
      You can't do that! Are you crazy? Well I am. I can't do this yet but I'd
      really like to. I'm working on it. If you have ideas on how this might
      be accomplished, send me an email. If you don't have a good idea, send
      me some coffee.
  
  BUGS AND CAVEATS
      *   There is currently no way to install documentation for multiple
          modules.
  
      *   This module only works with Perl 5.6.1 and higher. That's because
          earlier versions of Perl don't support putting objects in @INC.
  
  AUTHOR
      Brian Ingerson <INGY@cpan.org>
  
  COPYRIGHT
      Copyright (c) 2003. Brian Ingerson. All rights reserved.
  
      This program is free software; you can redistribute it and/or modify it
      under the same terms as Perl itself.
  
      See http://www.perl.com/perl/misc/Artistic.html
  



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About