Re: [Parseperl-discuss] PPI to get package/versions
Brought to you by:
adamkennedy
From: Todd R. <to...@cp...> - 2010-03-15 16:50:23
|
On Mar 10, 2010, at 9:07 PM, Elliot Shank wrote: > On 3/10/10 6:13 PM, Todd Rinaldo wrote: >> I want to use PPI to determine all packages and their $VERSION in a >> given pm file. I've determined how to get the list of packages in the >> file, but not the version. How can I do this? > > The only authoritative way of doing this is to load the module and check it at runtime. (Of course, determining which namespaces got twiddled in the process is difficult. > > You might want to look at http://search.cpan.org/dist/Module-Extract-VERSION/. > > If you want to do it yourself via PPI, I would probably set up a state machine that tracked what the current package is and when a $VERSION assignment is found, save it off in a stash of some sort. > > Alternatively, there's http://perlcritic.tigris.org/source/browse/perlcritic/trunk/distributions/PPIx-Utilities/lib/PPIx/Utilities/Node.pm?revision=3777&view=markup. You could use it to split your module up into namespaces and then look for $VERSION assignments in that. (I haven't released this yet due to wanting to move some code from Perl::Critic into the distribution first, but I'm still debating how to do it.) Elliot, thanks for your advice. It took me about 6 hours of struggling with PPI before I realized you were right and that PPI was a lost cause. The approach I've taken so far is to parse the output from $ver = `perl -e 'require $file; print $module::VERSION'`; What I've discovered is how many crazy things people try to do outside a sub in some perl modules. Also I often have to have the module and it's dependencies installed before my parsing will succeed. I played with removing use/require entries from the modules before I try requiring it but this often causes further breaks, especially when modules like Net::DNS (may it eternally burn in a dark place in hell for their evilness) try to alter their identity inside the BEGIN block. I've been forced to do a fallback to M::E::VERSION when I get weirdness in the output from my perl -e approach. I dislike this approach because it misses corner cases where multiple packages live inside a single .pm file. I'm sure you've seen many of these corner cases. How did you deal with them? It seems to me META.yml is desperately in need of a 'provides' section which could properly document the author's modules and versions as they intended. Has anyone heard any discussion of this idea ever? Thanks, Todd |