On Fri, Jan 26, 2001 at 02:08:01PM -0600, Garrett Goebel wrote:

> Discussion of RFC 271 and 194 on pre and post handlers for subroutines
> reminded me of Larry's desire for Perl 6 to support the coexistence of
> different versions of modules.
> 
> Besides http://dev.perl.org/rfc/78.pod, are there any RFC's which directly
> or indirectly relate to this?

Speaking as the author of RFC78, my official answer is ``I don't think
so.''  :-)  And RFC78 doesn't go as far as Larry has promised Perl6 will.

Advance apologies for being away so long; after a month I assumed things
had been wrapped up and there was no point in trying to catch up on the
old perl6-language mail.  Silly me.  Then I got a note from Mike Schwern
asking one of those ugly questions that spins out of this whole ugly
problem.

Sigh.

I believe that the versioning problems are solvable without doing major
damage to the existing modules structure.  This is detailed in the last
version of the RFC, but I am not certain if that version is available at
www.perl.org/perl6 - it is giving `access denied' at the moment.  The
last version is available at http://www.nnaf.net/~scs/Perl6/RFC78.html
(my version 1.3, stated in the text); I will update the perl.org one
once I can see if it's behind the times.

Shortly after the posting of RFC78, Larry replied:

> Quoting RFC78

> > Note that it may not be possible to satisfy conflicting requests.  If
> > module C<A> and module C<B> demand two different versions of the same
> > module C<C>, the compiler should halt and state the module conflicts.
>  
> Pardon me for sniping at a great RFC, but I already promised the CPAN
> workers that I'd make that last statement false.  There's no reason in
> principle why two modules shouldn't be allowed to have their own view
> of reality.  Just because you write Foo::bar in your module doesn't mean
> that Perl can't know which version of Foo:: you mean.

[[ . . . other details elided . . . ]]

Version 2.0 of RFC78 would have been an attempt to address the items
Larry raised.  It stalled out because (dammit), it's *hard*.  But it
seems the issue is still open, and I've had a few more ideas.  This
note lays out some issues and ideas.  If there's good discussion and
any sort of there's any sort of near-consensus or coherent streams of
thought it'll get rolled up into RFC78 2.X.

BUT: That's essentially the same comment I made Aug 9, and discussion
ground to a halt about four messages later.  So if you want me to
work, you gotta respond.  :-)

Read http://www.nnaf.net/~scs/Perl6/RFC78.html to see the starting
point.  And remember that all of this below is open to change if
anybody has a better idea.

Now that you've read RFC78, throw much of it out.  We'll retain
the ideas, but the current (perl5.6) version rules will continue
as they currently do.  Instead, I propose a new mechanism below.

Our goals are to do that while allowing:

  o  At load time for a module, a programmer must be able to specify
     vendor, author, and version on a per-module basis.  
  o  At execution time, a programmer must be able to specify vendor,
     author, and version for use in a script for when multiple versions
     may be present.
  o  There must be a clean, clear mechanism to install these modules
     by vendor/author/version without requiring the module actually
     be loaded (parsed).
  o  At load time, modules must be able to influence their sharability

RFC78 proposes a mechanism for specifying versions down to a very
fine grain of detail.  I propose that we retain the current perl
syntax/search model as it works today, but add an alternative form:

  use module (version; author; vendor);

Version numbers and search rules are as defined in RFC78, null means
'first found'.

Author is a comma- and/or whitespace-separated list.  Commas separate
preference order groups, whitespace separates no-preference order
groups (similar to version, see RFC78).  If the author field is null
the author list is used.  The default author list is null.  Pragmas
to manipulate the author list are needed.

Vendor works like author in most ways.  However, the default vendor
list for vendors is (PERL, site), consisting of the current perl
and site library trees.

Precedence and other rules are needed so that this can be understood
and so we don't break existing functionality:

Search precedence is by vendor, by author within vendor, by version
within author.

Author-specific modules are installed by author name within vendor
trees.

If we grant this rules, *all current CPAN functionality and perl
installations are preserved.*  IMHO this is a huge win.


A first cut at vendor/author pragmas:

These manipulate the vendor list:

  use vendor 'foo';             # Push vendor name 'foo' onto the vendor list
  use popvendor;                # Pop top of vendor list and discard
  use popvendor 'foo';          # Remove the topmost instance of 'foo'
  use rmvendor 'foo';           # Remove all instances of 'foo'
  use rmvendor '';              # Empty the vendor list
  use vendoralias 'bar' 'foo';  # vendor 'foo' can also be called 'bar'

Normally we assume a vendors files are in a directory with the same name
as the vendor.  For exceptions, we allow:

  use vendordir 'foo' 'path';   # Vendor foo tree is at <path>

If <path> is rooted, it's almost like doing

  use lib 'path';

except it associates a vendor name with it.  <path> is only searched
when that vendors name is requested for a load.  Thus doing this:

  use vendor 'foo';     # Always look in vendor foo first
  use vendordir 'foo' '/dir';

is nearly identical in result to doing this in current perl:

  use lib '/dir';

Unrooted vendor dirs mean that a given vendors libraries may be anywhere
(multiple places!) *inside* the perl tree (@INC), but scattered through
it.  It essentially changes @INC so that for each element in it, we also
search the relative portions of it.

Now repeat all of this discussion for author/authordir/authorinc pragmas.

Allow authors to be locked to a given vendor, ie,

  use author 'UUNET::scs';  # Only look for scs under vendor UUNET.

At this point, I think the installation strategy for modules is obvious
for vendor/author stuff.  Let's take one more step for version stuff.
Let's allow strongly versioned .pm files to be installed by version
number.  For example, version 1.2.3 of module.pm could be installed as
    .../lib/perl/..../module.pm-1.2.3
Now perl can determine if a given module is a given version without
having to load/parse it.  Of course, if 'module.pm-1.2.3' contains
    $VERSION='1.1';
it's a compile time error with appropriate error message.

The system default version of module.pm is installed as simply 
`module.pm'.  I suspect that many sysadmins will want to make module.pm
a symlink to module.pm-version.


Ugh.  This note is too long already.  Some quick points before calling
it a night:

A pre-index of a module tree might be a big win; I can see us
getting into Search Path Hell here.

Aliasing for complex vendor/author/version namespaces is needed.  If
multiple simultaneous loads are desired, we should be able to do
  use module (version1;authorA;vendorX) as 'foo' qw(new);
  use module (version2;authorB;vendorY) as 'bar' qw(new);
  . . .
  my v1 = foo::new();
  my v2 = bar::new();

Detailed v/a/v specification is probably desirable in individual calls.
One possible syntax is:
  use module (version1;;) qw(new);
  use module (version2;;) qw(new);
  . . .
  my v1 = new@(version1;;);
  my v2 = new@(version1;;);
This is horribly ugly, but it's late and I'm tired. :-)

A module which defines objects that use a class variable (only one
instance of a $var no matter how many instantiations of the object)
might be severely broken if more than one version of the module is
loaded simultaneously.  We should set up some pragmas so that a module
can forbid simultaneous loading (and that should be the default), permit
it, or permit it only when sufficiently similar version/author/vendor
combinations are loaded.  I strongly suspect this last *has* to be done
in the BEGIN blocks; run-time is too late.

Devel::TraceLoad is an indispensable tool when doing complex and
sensitive loads; it should be extended to handle vendor, author and
version reporting and moved into the perl6 core.

Rules/messages need to be defined for version mismatch.

And surely I've forgotten lots of things.... but I think there is a
minimally acceptable proposal here.

Reply via email to