12

In Bar.pm, I declare a class with an authority (author) and a version:

class Bar:auth<Camelia>:ver<4.8.12> {
    }

If I use it in a program, how do I see which version of a module I'm using, who wrote it, and how the module loader found it? As always, links to documentation are important.

This question was also asked on perl6-users but died before a satisfactory answer (or links to docs) appeared.

Another wrinkle in this problem is that many people aren't adding that information to their class or module definitions. It shows up in the META.json file but not the code.

Pat
  • 36,282
  • 18
  • 72
  • 87
brian d foy
  • 129,424
  • 31
  • 207
  • 592
  • 1
    ["auth" is "auth" and not "author"](https://irclog.perlgeek.de/perl6/2017-04-20#i_14460369). – raiph Jul 03 '17 at 18:14
  • 1
    "[auth] information ... shows up in the META.json file but not the code." [TimToady, on this problem](https://irclog.perlgeek.de/perl6/2017-04-20#i_14460332): "force a new version when a module is patched ... I sent a pr to jnthn to fix a bug, but forgot to increment the patchlevel, so zef doesn't see it ... name/ver/auth [must] correspond to a unique text if installed into an official library [OR] include a [crypto] hash as part of the identity [OR] git revision ... it's gonna be a nightmare if you can't name the "correct" version you're looking for uniquely". – raiph Jul 03 '17 at 18:43

1 Answers1

12

(Probably not a satisfying answer, because the facts of the matter are not very satisfying, especially regarding the state of the documentation, but here it goes...)


If the module or class was versioned directly in the source code à la class Bar:auth<Camelia>:ver<4.8.12>, then any code that imports it can introspect it:

use Bar;

say Bar.^ver;   # v4.8.12
say Bar.^auth;  # Camelia

# ...which is short for:
say Bar.HOW.ver(Bar);   # v4.8.12
say Bar.HOW.auth(Bar);  # Camelia

The ver and auth methods are provided by:


Unfortunately, I don't think the meta-object currently provides a way to get at the source path of the module/class.
By manually going through the steps that use and require take to load compilation units, you can at least get at the prefix path (i.e. which location from $PERL6LIB or use lib or -I etc. it was loaded from):

my $comp-spec = CompUnit::DependencySpecification.new: short-name => 'Bar';
my $comp-unit = $*REPO.resolve: $comp-spec;
my $comp-repo = $comp-unit.repo;
say $comp-repo.path-spec;  # file#/home/smls/dev/lib
say $comp-repo.prefix;     # "/home/smls/dev/lib".IO

$comp-unit is an object of type CompUnit.
$comp-repo is a CompUnit::Repository::FileSystem.
Both documentations pages don't exist yet, and $*REPO is only briefly mentioned in the list of dynamic variables.


If the module is part of a properly set-up distribution, you can get at the meta-info defined in its META6.json (as posted by Lloyd Fournier in the mailing list thread you mentioned):

if try $comp-unit.distribution.meta -> %dist-meta {
    say %dist-meta<ver>;
    say %dist-meta<auth>;
    say %dist-meta<license>;
}
smls
  • 5,738
  • 24
  • 29
  • 2
    I'd like to explore the CompUnit stuff in more detail, but I think this answer is about as good as it gets. I came up with basically the same stuff. Thanks! – brian d foy Jul 03 '17 at 20:51
  • Can you specify what is the problem with the documentation? I'd like to help there... – jjmerelo Apr 09 '18 at 05:34
  • 1
    @jjmerelo: I think I was referring to the two incomplete `Metamodel::` doc pages I linked to near the top, as well as the fact that this information as a whole isn't easily available in the docs (ideally in one place) but rather had to be collected from the docs, specs, Rakudo source code, and experimentation. – smls Apr 16 '18 at 06:26