I'm learning Perl. As an exersize, I try to print all installed Mojolicious modules. I'm using Strawberry Perl and don't have grep
installed.
My naive try is:
perl -wE "for (sort `cpan -l`) { chomp; say if index($_, 'Mojo') == 0; };"
I found out that cpan -l
returns a list. I expected a string, but never mind. I sort
the returned list, chomp
each record and say
the ones that start with 'Mojo'.
It rather works, but prints each line twice:
Mojolicious::Sessions undef
Mojolicious::Sessions undef
Mojolicious::Static undef
Mojolicious::Static undef
Mojolicious::Types undef
Mojolicious::Types undef
Mojolicious::Validator undef
Mojolicious::Validator undef
Mojolicious::Validator::Validation undef
Mojolicious::Validator::Validation undef
What it is wrong that prints each record twice?
Edit:
I run the code under Cent OS. It looks like it works fine but have two versions of the libs installed.
perl -we 'for (sort `cpan -l`) { chomp; print $_, "\n" if index($_, "JSON") == 0; };'
JSON::PP 4.02
JSON::PP 4.04
JSON::PP::Boolean 4.02
JSON::PP::Boolean 4.04
Edit 2:
As recommended by @zdim, I checked the file paths of the installed modules. It appeared that there are doubled installations:
whichpm -a Mojolicious
C:\Strawberry\perl\site\lib\Mojolicious.pm
C:\Strawberry\perl\vendor\lib\Mojolicious.pm
whichpm -v Mojolicious
whichpm: WARNING: DUPLICATE module files found for 'Mojolicious':
C:\Strawberry\perl\vendor\lib\Mojolicious.pm
Mojolicious 8.22 (non-core) C:\Strawberry\perl\site\lib\Mojolicious.pm
It looks like the question was wrong.
A possible reason for the duplicated installation can be inproper modules update. After installing Strawbery I used the following command:
cpan-outdated -p | cpanm
Thank you guys for the help. It looks like it was the wrong question. I accept the given answer and will open a new 'better' question.
Not sure what cpan
does and its man page is sprawling for me. Could it be listing modules from two Perl versions? Or there are indeed two versions of modules installed?
Here is another option, with core ExtUtils::Installed
perl -MExtUtils::Installed -MList::Util=max -wE'
$obj = ExtUtils::Installed->new;
@mods = sort $obj->modules;
$max_len = max map { length } @mods;
printf("%-${max_len}s -- %s\n", $_, $obj->version($_)) for @mods'
This prints all of them. To see just the ones starting with Mojo
change the last line to
/^Mojo/ and printf("%-${max_len}s -- %s\n", $_, $obj->version($_)) for @mods'
The /^Mojo/
is a regex that tests $_
(by default) for whether it starts with (^
anchor) the literal string Mojo
. This is I think clearer than using index
, and is idiomatic (more readily understood).
But printf has for the field width the length of the longest module name, found before filtering, which is likely too wide for the filtered list. So for nicer output you can first filter with grep
my @mods_filtered = sort grep { /^Mojo/ } $obj->modules;
my $max_len = max map { length } @mods_filtered;
printf("%-${max_len}s -- %s\n", $_, $obj->version($_)) for @mods_filtered;
All this should be in a small utility script; the one-liner above is for copy-paste testing.
See documentation for details on what this module does.
Also see this post, with code for another option -- to search for files directly.