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

Fellow Perlmonks,

Updated
Ok, so does anyone have any other suggestions for -
if finding a file recursively doesn't exist, create it.
if it does exist, move on.

Trying to put together some code that looks for a file matching a pattern, and if it doesn't exist, creates it with the content stored in a variable. The &wanted sub below does a pattern search as /$currentstoryid/. The problem is it keeps looking for the same $currentstoryid. Never gets updated by the foreach loop, like it's some kind of private variable that gets stuck. Any ideas? Any help is appreciated.

ILC

if (my @entries = $html->content =~ /<h2><a href="\/entry.*?<br \/>\s+ +?<br \/>/gs) { @entries = reverse @entries; foreach my $entry (@entries) { $entry =~ /<h2><a href="\/entry\/(\d+)\/"/; my $currentstoryid = $1; my $exists; &find(\&wanted, $sitedir); sub wanted { if (/$currentstoryid/) { $exists = 1; return $exists; } } if ($exists) { my $datedir = strftime "%Y/%m/%d", localtime; my $freshentry="$sitedir/$datedir/$currentstoryid.txt"; print " Creating ", $freshentry, "\n"; system ("mkdir", "-p", "$sitedir/$datedir"); open(NEWSTORY, ">> $freshentry"); print NEWSTORY "<font color=\"#dd3333\">$site</font>\n +"; print NEWSTORY "$entry\n"; close (NEWSTORY); } } }
Buddha bless you.

Replies are listed 'Best First'.
Re: file::find subroutine not getting new values
by sgifford (Prior) on May 18, 2004 at 16:25 UTC

    Because you're declaring the wanted sub inside an enclosing block containing lexical (my) variables, those variables create closures, and when the sub uses these variables, it gets the copies that were in existence when it was first compiled. The next time through the loop, a new variable is created, and the variable in the sub and outside it no longer refer to the same thing.

    The easiest fix is to not use lexical variables. Declare $currentstoryid and $exists with our instead of my, and the problem goes away. Another solution is to create a new anonymous sub for each call to find:

    my $currentstoryid = $entry; my $exists=0; &find( sub { if (/$currentstoryid/) { $exists = 1; return $exists; } }, $sitedir);
      Took your anonymous sub advice and it works like a charm. Thanks for everything. -ILC
      Buddha bless ya'll.