Re: variable "inheritance"; viral $VERSION
by Abigail-II (Bishop) on Mar 09, 2003 at 03:17 UTC
|
Unfortunally, CPAN doesn't know how to deal with that.
It looks for lines that assign, or appear to assign to
a variable $VERSION. If you are inheriting
$VERSION, CPAN will think the module doesn't
have a version.
Whether that's going to be a problem for you or not, I
do not know.
Abigail | [reply] [d/l] [select] |
|
|
Right, except that all of these classes get packaged together in the same CPAN module (hence the My::Package nomenclature). My understanding is that Makefile.PL's VERSION_FROM does actually compile a module, and read its $VERSION variable. Does it really only parse the file, not compile it?
| [reply] |
|
|
CPAN does track the VERSION of each .pm file,
and it will not install a .pm file if it thinks
the one already installed is newer, regardless what the
version number is of the package. (In fact, as far as I
can tell, there's no relationship between the version of
the package (the number in the tar file), and the versions
of the .pm files).
As far as CPAN is concerned, all the .pm files without
a VERSION assignment in the file itself do not have a VERSION.
It'll list them as undef. Whether it will then
actually replace an already installed file with a newer one,
I do not know. For me, CPAN usually doesn't do what I mean,
so I wouldn't dare take the risk.
Abigail
| [reply] [d/l] |
|
|
|
|
|
|
| [reply] [d/l] |
Re: variable "inheritance"; viral $VERSION
by Anonymous Monk on Mar 09, 2003 at 03:08 UTC
|
Why would you like this?
The point of $VERSION is to document what version of the code you have. When the $VERSION of one package reflects the version of a file appearing elsewhere you make it even easier for $VERSION to not represent what it is supposed to.
Why do you want a $VERSION with these properties?
If you want to do something so counterproductive, you certainly can. One appropriately silly way is to create a module named "am.pm" with a method named "I" which loads a module, inherits from it, and sets $VERSION. Then in every module you only need:
package Bar;
use am;
I am "Foo";
...
The implementation of am::I is left as an exercise for the reader. | [reply] [d/l] |
|
|
You didn't read my original post carefully. I don't need to implement "I am 'Foo'", I can simply "use My::Package::Version" wherever I want it.
The classes in my package all have "My::Package::*" names, and I only want $VERSION to propagate through all of these packages, not any other. I want a simple way to keep $VERSION "synchronized" throughout all classes of my package, without having to type something in all of them.
| [reply] |
|
|
I did read your original post.
My suggestion adds typing. Yes. It also removes typing. You no longer need the "use Foo" line. You no longer need to declare your @ISA. The typing saved exceeds the typing added. I consider that reasonable if your intention is to save typing.
Now can you explain why on Earth you would want this?
| [reply] |
|
|
|
|
Re: variable "inheritance"; viral $VERSION
by bbfu (Curate) on Mar 09, 2003 at 07:56 UTC
|
The answer to your specific question as to why your code doesn't export the version to My::Package::A is that, as you already noted, caller(2) is main for some reason. However, if you do a full call stack trace from the import, you will see that My::Package::A is included but there are two instances of main in between it. I don't really have any idea why that is (perhaps a more enlightened monk can explain) but this causes the condition of your while loop to fail and thus not go futher into the call stack.
I believe what you want, and probably intended to do, is to simply skip packages not begining with My::Package but continue the loop. Like so:
./My/Package/Version.pm:
package My::Package::Version;
use strict;
use vars qw(@ISA @EXPORT $VERSION);
use Exporter;
@ISA = qw(Exporter);
@EXPORT = qw($VERSION);
$VERSION = 3.14;
sub import {
my $i = 0;
my $pkg = caller(0);
print "Import Caller Trace:\n";
while($pkg) {
print " Called from package $pkg\n";
# Note that these tests have been moved from the
# loop condition to inside the loop so the loop
# will not terminate if it fails.
if($pkg =~ /^My::Package::/ and not defined ${"$pkg\::VERSION"}) {
print " (Exporting VERSION to $pkg)\n";
__PACKAGE__->export_to_level($i+1);
}
$pkg = caller(++$i);
}
}
./My/Package/B.pm:
package My::Package::B;
use My::Package::Version;
print "My::Package::B loaded.\n";
1;
./My/Package/A.pm:
package My::Package::A;
use My::Package::B;
@ISA = ('My::Package::B');
print "My::Package::A loaded.\n";
1;
./tst.pl:
#!/usr/bin/perl
use lib '.';
use My::Package::A;
print "\$My::Package::A::VERSION = $My::Package::A::VERSION\n";
Output of ./tst.pl:
Import Caller Trace:
Called from package My::Package::B
(Exporting VERSION to My::Package::B)
Called from package main
Called from package main
Called from package My::Package::A
(Exporting VERSION to My::Package::A)
Called from package main
Called from package main
Called from package main
Called from package main
Called from package main
My::Package::B loaded.
My::Package::A loaded.
$My::Package::A::VERSION = 3.14
bbfu
Black flowers blossum
Fearless on my breath | [reply] [d/l] [select] |
|
|
Excellent, thank you. I figured once I had hit "main", that the party was over. I never thought to keep looking.
| [reply] |
Re: variable "inheritance"; viral $VERSION
by chromatic (Archbishop) on Mar 09, 2003 at 02:57 UTC
|
| [reply] [d/l] |
|
|
That doesn't help people that want to "use My::Package::A 3.14" to get versioning.
| [reply] |
Re: variable "inheritance"; viral $VERSION
by Zaxo (Archbishop) on Mar 09, 2003 at 06:59 UTC
|
| [reply] |
CVS
by zby (Vicar) on Mar 09, 2003 at 03:59 UTC
|
How about using a versioning system like CVS (or Subversion)? Perhaps it would eliminate your problems. | [reply] |
|
|
| [reply] |
|
|
OK - that was just a suggestion. What I meant was actually that perhaps when you use the CVS tags you would not need a version variable.
| [reply] |