On Wed, Aug 09, 2000 at 10:44:03AM -0700, Larry Wall wrote:
> : 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 . . .
No problem, I don't feel sniped at.
> . . . 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.
Near the end of the RFC this topic does come up; see it directly at
<http://www.nnaf.net/~scs/Perl6/RFC78.html#Alternative_Idea_Module_Versio>.
That section was much longer in my unreleased drafts, but did include
some discussion on disambiguation when multiple versions of the same
module are loaded. In the RFC I wrote off this idea with ``In This Way
Lies Madness, but perl has done stranger things.''
If we want to open that can of worms I'm willing to pitch in. I'll even
continue on with the task of maintaining the RFC, or starting another
if appropriate. But I'd barely started thinking about this issue with
respect to perl until a couple of days ago, so folks who are much more up
to speed on language/inheritence/etc are going to have to carry the load.
Turning back to some specific comments made by Larry and by Dan Sugalski:
LW> The larger view of it is how to support package aliasing. A package
LW> name is essentially the name of a public interface. Suppose you
LW> have one interface, but two or more different implementations of
LW> that interface by different people. Each might have their own
LW> version sequence.
Package aliasing should certianly be allowed; the RFC already contains
a suggestion for it:
use foo <3.0 as foo_old;
use foo =3.0. as foo;
use foo >3.0. as new_foo;
Using the alias gets you what you need.
Your comment above implies that CPAN may (will be allowed to) contain
modules of the same name and same version by different authors. Is this
correct? If so (shudder), what happens currently when both are installed?
I presume one simply overwrites some or all of the other.
If that's the intent, then yes, author name must become part of the
package identifier. Rather than change the meaning of "ref $object"
unexpectedly, I'd add one or more alternate forms of ref. Off the
top of the head, something like
( $version, $class ) = vref $object; # ref with version
$version = vref $object; # scalar context gets version
( $author, $class ) = aref $object; # ref with author
$author = aref $object; # scalar context gets author
( $version, $author, $class ) = fref $object; # get all
# Scalar context gets a string suitable for select the
# exact object in use
$fq_name = fref $object;
if ( $fqname eq fref $other_object )...
LW> Another question is whether the two different versions of the "same"
LW> module are going to stomp on each other? (Not in package space, since
LW> the packages are distinguished internally, but how about in the
LW> filesystem?)
If we include author name along with the version number in the file system
namespace (gawd, I can't believe I just wrote that), then clobbering
won't happen. IMHO this feature is no more difficult to add to the
install process than adding version numbers; it implies tho that we
need a $AUTHOR var in all modules and to allow for it in module `version'
specifications. Again, off the top of the head, we could allow a string
(any string that would not be confused with a version number) to indicate
the author:
use foo CONWAY <=1.3 as foo_good;
use foo GATES >1.3 as foo_bad;
use foo * as foo_desperate;
As long as there's no author names `as', we're cool. I suspect the
proposed syntax in the RFC could be extended to handle this unambiguously
both for run/compile-time module naming and for installation, but need
to think it thru.
DS> Does that mean, then, that when module A does a "$C::bar = 1" it
DS> affects a different package namespace than module B doing a
DS> "$C::bar = 2"?
LW> Presumably.
Yes, that's how I'd see it too. Which creates a real problem for
modules which do things like
package foo;
....
{
my $hidden_var;
sub new {
if ( $hidden_var ) {
do x;
} else {
do y;
}
}
}
Now there are two copies of $hidden_var while the module clearly expects
only one. Either this kind of construction will have to be avoided,
or some mechanism developed which allows multiple version of a module
to somehow share important data which is otherwise hidden by such tricks.
IMHO, module authors should be able to forbid multi-loads across
sufficiently different versions of the module (ie, all 2.Xs can work
together but 2.X cannot mix with 1.X or 3.X).
LW> To me, it really just means that the *real* name of the package
LW> includes the implementation (author?) and version, but that when
LW> you say
LW>
LW> use C;
LW>
LW>you're just choosing to wildcard both the implementation and version.
Yes. To take this a step further, this is equivelent to aliasing
use foo * >=0.0 as foo ;
ie, accept any version of module foo by any author, and refer to it
as simply foo. But `foo' is actually an alias for the fully qualified
name of the module.
Specifying those FQMNs could be a bitch. IMHO we can't do
module::author::version::item
because of possible name conflicts between authors and sub-modules.
Does FOO::CARP refer to the CARP submodule of FOO, or to the FOO module
written by CARP? Wotta pain.
I'd prefer that in program namespace we choose a different separator
for these subdivisions, eg,
module'author'version::item
One could argue that this construction ought to be part of the use
statement as well:
use foo'*'=1.3 ; # Any authors version 1.3
use bar'CONWAY as bar; $ Any CONWAY version
use foo''1.0-2.0;
....
Consistancy is probably a virtue.
LW> Think about the long names of fonts for an example of how far this
LW> can be taken.
DB> Would this be "Taken to its logical and sensible conclusion" or "Taken as
DB> far as it can possibly go, though it you turn around and look *really* hard
DB> with binoculars you can see where you crossed the line, way back there by
DB> the horizon"?
This is a non-issue. We only have a two-dimensional space for each module
name, version by author. Or am I missing something?
We need to answer Dans question:
DS> . . . If you use C in package A, and also in package B, which do you
DS> see when you're in main and access $C::bar?
LW> I dunno. I don't imagine the situation will arise that often.
It may not happen often, but once is enough. IMHO the answer is `in load
order' unless the programmer does something explicit to resolve the
issue. IMHO careful programmers would be explicitly loading C into main
themselves rather than depending on some other module to do it for you.
Then you've taken direct control. Should you need to specificly manipulate
some other packages use of C, then you've got to do:
A::C::foo();
B::C::foo();
OK, let's let someone else get into the conversation.