Perl Constant seems not to work

constants, perl

Solution

It has nothing to do with constants.

>perl -wE"$_ = '.txt'; say qr/\.jar$/ ?1:0;"
1

>perl -wE"$_ = '.txt'; say /\.jar$/ ?1:0;"
0

>perl -wE"$_ = '.txt'; say $_ =~ qr/\.jar$/ ?1:0;"
0

`qr//` compiles a regex pattern and returns it, while the match operator (`m//` aka `//`) preforms a regex match.

Since `qr//` always returns something true (a compiled regular expression), `return unless qr/\.jar$/;` will never return.

`=~ qr/\.jar$/` works because `=~` implies a match operator if the RHS operand isn't a match operator (`m//`), a substitution operator (`s///`) or a translate operator (`tr///`).

my $re = qr/\.jar$/;
$_ =~ $re

is short for

my $re = qr/\.jar$/;
$_ =~ /$re/

which is long for

my $re = qr/\.jar$/;
/$re/

If you omit both the `//` and the `=~`, you don't have a match operator anymore.

Problem

I have this: ``` use constant JAR_FILE => qr/\.jar$/; my @dir_list = ...; my @jar_list; find ( sub { return unless -f; return unless JAR_FILE; #THIS IS THE TROUBLED LINE push @jar_list, $File::Find::name; }, @dir_list; say join ": ", @jar_list; ``` This prints out all of the files in `@dir_list` -- jar files and non jar files; However, this: ``` use constant JAR_FILE => qr/\.jar$/; my @dir_list = ...; my @jar_list; find ( sub { return unless -f; return unless $_ =~ JAR_FILE; #Now explicitly do the comparison push @jar_list, $File::Find::name; }, @dir_list; say join ": ", @jar_list; ``` prints out only jar files. And this also only prints out jar files: ``` # use constant JAR_FILE => qr/\.jar$/; my @dir_list = ...; my @jar_list; find ( sub { return unless -f; return unless /\.jar$/; #Use regex and not constant regex. push @jar_list, $File::Find::name; }, @dir_list; say join ": ", @jar_list; ``` Why does the first one `return unless JAR_FILE;` not work while `return unless $_ =~ JARFILE;` and `return unless /\.jar$/;` both work?

Original source