I am attempting to use a Path::Iterator::Rule "Custom rule subroutine".
I have a regexp during the buildup of my rules, which determines whether the custom rule subroutine is used. If it indicates to use the subroutine, then its capture group $1 at this point holds some text that I want to match in the subroutine to filter for certain pathnames.
With the naive approach, it seems that the $1 or $var variable in my regexp is only expanded at the time of the regexp/subroutine being run. At this point, the variable is no longer valid and could have been overwritten by some other value. Naive code:
my $rule = Path::Iterator::Rule->new;
if ($id =~ /^([0-9A-F]{2})/) {
my $int = $1;
$rule->and( sub { m#/INT $int# } );
}
Resulting errors are many times this line:
Use of uninitialized value $int in regexp compilation at [redacted]/proj/intlist/intlist.pl line 1167.
I found that it appears to work if I use a "postponed" regular subexpression like so:
my $rule = Path::Iterator::Rule->new;
if ($id =~ /^([0-9A-F]{2})/) {
my $int = $1;
$rule->and( sub { m#/INT (??{ "$int" })# } );
}
Is this a correct approach? Are there other ways to interpolate a variable at the time of adding the custom rule subroutine, so that the rule doesn't refer to the variable later but rather uses the text that it used to hold?
|
I feel like this question has been asked in the past but I could not find it in the search.
So I am running this code snippet from Dave Cross' blog titled, Summarizing a Month of Git Activity with Perl (and a Little Help from AI) and I ran into a new feature of Perl -- subroutines that take named arguments. We had prototypes in the past but people said they were wonky so I avoided them for the most part.
So here I am trying to use this thing and I start getting a weird error:
#!/usr/bin/perl -w
use strict;
# LEARN: weird -- the method has named parameters ... since v5.36
sub commits_for_month ($repo, $since, $until) {
my $cmd = sprintf(
q{git -C %s log --since="%s" --until="%s" --pretty=format:"%%s"},
$repo, $since, $until
);
my @commits = `$cmd`;
chomp @commits;
return @commits;
}
1;
I get...,
llegal character in prototype for main::commits_for_month : $repo, $si
+nce, $until at ./gitter.pl line 7.
Global symbol "$repo" requires explicit package name (did you forget t
+o declare "my $repo"?) at ./gitter.pl line 10.
Global symbol "$since" requires explicit package name (did you forget
+to declare "my $since"?) at ./gitter.pl line 10.
Global symbol "$until" requires explicit package name (did you forget
+to declare "my $until"?) at ./gitter.pl line 11.
./gitter.pl had compilation errors.
My Perl version:
This is perl 5, version 40, subversion 1 (v5.40.1) built for x86_64-li
+nux-thread-multi
...
When I look this up using Google's handy-dandy AI it tells me all about the normal way to get passed-in parameters in a subroutine and then tells me that this new syntax is available in v5.36. So I add,
use v5.36;
To my code and voila, the code compiles,
perl -c ./gitter.pl
./gitter.pl syntax OK
Dave's example didn't specify the version like this in his code. Is there something in my environment I am supposed to set to avoid this from happening?
Celebrate Intellectual Diversity
|