Re: code references - how to

[email protected] ("John W. Krahn")
Newsgroups perl.beginners
Message-ID <[email protected]>
Dermot wrote:
> Hi All,

Hello,

> I was have to create a script to search and find files. The files will
> end in 'a.txt', 'b.txt', 'c.txt', so a record could have 123a.txt,
> 123b.txt, 123c.txt.
> 
> There may be lots of ways to achieve my goal but I got curious about
> how to create a structure that, for each record would store the
> associated files. Below is what I started out with. The hash tries 3
> ways to either return a code reference or a true/false value if the
> file exists. I have tried putting junk values in the hash values - sub
> { return -e "$File::Find::dir/${num}Z.txt"} - but it always ouputs
> with a YES.
> 
> So how do you create a code reference in this context, should I create
> a code reference or use something else and what should I be test the
> hash values for?
> 
> 
> 
> #!/usr/bin/perl
> 
> use strict;
> use warnings;
> use File::Find;
> 
> my $root = shift;
> my @records;
> 
> find(\&wanted, $root);
> 
> sub wanted {
> 
>  my ($num,$let) = ($_ =~ /(\d+)([\w{1}])\.txt/);

Your character class [\w{1}] could also be written as [}{\w].  Did you 
want $let to also contain numerical digits or '_' or '{' or '}'? 
Perhaps what you meant to do is:

    my ( $num, $let ) = /^(\d+)([a-zA-Z])\.txt$/;


>  print $_, "  $num Let=$let\n" if ($let !~ /i|j|k/) ;

/i|j|k/ would be better as /[ijk]/.


>  my @sizes = qw(a b c d e f h i j k);
> 
>  my %file = (
>         name    => "f001/$num",
>         a       => sub { return -e "$File::Find::dir/${num}a.txt"},
>         b       => sub { return -e "$File::Find::dir/${num}b.txt"},
>         c       => sub { return does_exist("$File::Find::dir/${num}c.txt") },
>         j       => \&does_exist("$File::Find::dir/${num}c.txt"),

Each of the keys 'a', 'b', 'c' and 'j' contains a reference to a subroutine.


>         );
>  push(@records, \%file);
> 
> }
> 
> sub does_exist {
>  my $file = shift;
>  return sub { return -e $file };
> }
> 
> for (@records) {
>  print $_->{name},"\t";
>  foreach my $l (qw/a b c j/) {
>         if ($_->{$l}) {

Here you test whether a code reference is true or false but a reference 
is *always* true.  Perhaps you meant to dereference the code reference:

          if ( $_->{$l}->() ) {


>                 print "YES\t";
>         }
>         else {
>                 print "No\t";
>         }
>  }
>  print "\n";
> }


John
-- 
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order.                            -- Larry Wall
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.