Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

while following perl hack book

by convenientstore (Pilgrim)
on Feb 04, 2008 at 02:28 UTC ( [id://665889]=perlquestion: print w/replies, xml ) Need Help??

convenientstore has asked for the wisdom of the Perl Monks concerning the following question:

While folloing perl hack book's example(chap 1 hack 5; it's about auto completion in vim and putting all modules in one file to search from), I found it very surprising that it wasn't working on my linux box
I am sure it was working somewhere else and I overlooked something, I digged in and see if I could make it work on my box

Finally results being at the bottom, and looking at the file that I created after running the script looks like it's working
Can some more experienced monks fix it so that I can see what I should have done instead of what I did?
My maine question is, when encountered below
## Need to get rid of directories, such as 5.8.8 or i386-l +inux-thread-multi ## 5.8.8::URI.pm ## i386-linux-thread-multi::Net::DNS::RR::MG.pm $file =~ s{^ +\d+\.\d+\.\d+::}{}g; $file =~ s{^ ?[^A-Z]+::}{}g; $file =~ s/^ +//g;
Looks like I could have gotten rid of directories more simpler way then applying 3 regex back to back to back?
use File::Find 'find'; # Where to create this list... my $LIST_DIR = "$ENV{HOME}/.vim_extras/" my $LIST_FILE = "file_that_lists_every_installed_Perl_module"; # Make sure the directory is available... unless (-e $LIST_DIR ) { mkdir $LIST_DIR or die "Couldn't create directory $LIST_DIR ($!)\\n"; } # (Re)create the file... open my $fh, '>', "$LIST_DIR$LIST_FILE" or die "Couldn't create file '$LIST_FILE' ($!)\\n"; # Only report each module once (the first time it's seen)... my %already_seen; # Walk through the module include directories, finding .pm files... for my $incl_dir (@INC) { find { wanted => sub { my $file = $_; # They have to end in .pm... return unless $file =~ /\\.pm\\z/; # Convert the path name to a module name... $file =~ s{^\\Q$incl_dir/\\E}{ }; $file =~ s{/}{::}g; $file =~ s{\\.pm\\z}{ }; # Handle standard subdirectories (like site_perl/ or 5.8.6 +/)... $file =~ s{^.*\\b[a-z_0-9]+::}{ }; $file =~ s{^\\d+\\.\\d+\\.\\d+::(?:[a-z_][a-z_0-9]*::)?}{ +}; return if $file =~ m{^::}; # Print the module's name (once)... print {$fh} $file, "\\n" unless $already_seen{$file}++; }, no_chdir => 1, }, $incl_dir; }
so I changed to below and works but how I did it looks very inefficient..
for my $incl_dir (@INC) { find { wanted => sub { my $file = $_; # They have to end in .pm... return unless $file =~ /.+\.pm/; # Convert the path name to a module name... $file =~ s{^\Q$incl_dir/\E}{ }; $file =~ s{/}{::}g; # Handle standard subdirectories (like site_perl/ or 5.8.6 +/)... ## 5.8.8::URI.pm ## i386-linux-thread-multi::Net::DNS::RR::MG.pm $file =~ s{^ +\d+\.\d+\.\d+::}{}g; $file =~ s{^ ?[^A-Z]+::}{}g; $file =~ s/^ +//g; return if $file =~ m{^::}; # Print the module's name (once)... #print "printing\n"; print {$fh} $file, "\n" unless $already_seen{$file}++; }, no_chdir => 1, }, $incl_dir;

Replies are listed 'Best First'.
Re: while following perl hack book
by Util (Priest) on Feb 04, 2008 at 04:28 UTC

    The problem with the original, as you posted it, is that all the backslashes have been doubled. Change all occurances of '\\' into '\', and it works fine.

    The downloadable code from O'Reilly does not have the doubled backslashes, (and neither does the copy of the page at Google Books), but it is missing a trailing semi-colon from the $LIST_DIR line.
    In the tarball, the path is perl_hacks_examples/productivity_hacks/autocomplete_perl_identifiers_in_vim/find_pm_files.pl.

      hey thanks!
      didn't realize they have downloadable codes.
      Downloaded them and will be going over them.
      I still am however looking for ways to optimize that code (but I am sure point of that book wasn't about optimizing

      UPDATE: can someone please explain to me what wanted=> sub is all about?
      I thought wanted() was a simple sub? so I am not sure what wanted=> sub is doing in the code
      { find { wanted => sub { ## code.... }, no_chdir => 1, }, $incl_dir; }
        sub { some code } generates an anonymous subroutine and returns a reference to it. So:
        find( { wanted => sub { blah blah } }, @dirs );
        is the same as
        sub foo { blah blah } find( { wanted => \&foo }, @dirs );
        but without declaring a separate, named subroutine.

        Update: fixed to pass hashref and array

        ++ysth is correct about named vs anonymous subroutines. Another confusing issue is that the first argument to find() can be either a code reference or a hash reference. In the simpler case, where you have no special options to set, you just make the first argument a *code* reference; a reference to the "callback" sub. The sub is always named "wanted" in the documentation, but it can have any name, or be a anonymous sub.

        find( \&some_subroutine, @directories_to_search, );
        If you need to set a special option in find(), like 'no_chdir', then you pass a *hash* reference as the first argument. The code reference (that you would have used as the first argument in the simpler case) becomes the 'wanted' option.
        find( { wanted => \&some_subroutine, other_option => 'other_option_value', # ... }, @directories_to_search, );

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://665889]
Approved by lidden
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2024-04-16 13:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found