I have read some arguments at the command line:
#!/usr/bin/env perl
use 5.0360;
use warnings FATAL => 'all';
use autodie ':default';
use Devel::Confess 'color';
use Getopt::ArgParse;
my $parser = Getopt::ArgParse->new_parser(
help => 'This script finds and pretty-prints a line within a CSV file',
);
$parser-> add_args(
['-file', '-f', required => 1, type => 'Scalar'],
['-regex', '-r', required => 1, type => 'Scalar'], # regex pattern within each line
['-sep' , '-s', required => 0, type => 'Scalar']
);
my $args = $parser->parse_args(@ARGV);
my $sep = $args->sep // ',';
my $regex = $args->regex;
my @header;
say $args->regex;
open my $fh, '<', $args->file;
while (<$fh>) {
chomp;
if ($. == 1) {
@header = split $sep;
next
}
next unless /$regex/; # key point
say __LINE__;
# code later
}
the problem here is that the regex comparison
next unless /$regex/
works, but
next unless /$args->regex/
does not work, even though the two are copies of each other via my $regex = $args->regex;
Strangely, I can use $args->file
but cannot use $args->regex
Why does $args->regex
work like this? What is the correct terminology for $args->regex
? It's not a hash, it's some sort of object.
CodePudding user response:
You can't interpolate method calls into a string. I guarantee you that $args->file
doesn't work either here. Note that $args->regex
is not a field access but a method call, equivalent to $args->regex()
.
When interpolating a variable into a quote-like context (including regexes), you can use scalars, arrays, and array/hash field accesses.
I think that using a named variable my $regex = $args->regex
is the clearest solution here. But if you really want to interpolate arbitrary expressions into a string, you can use a trick: you can interpolate arrays @foo
, thus also an array dereference @{ ... }
. Then:
next unless /@{[ $args->regex ]}/;