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