Proper way to use a Moose class attribute in a reg

2019-08-08 17:02发布

I now know that the proper way to access Moose class attributes is to ALWAYS go through the accessor method that is automatically generated by Moose.

See Friedo's answer to my previous question for the reasons why.

However this raises a new question... How do you ensure Moose class attributes are handled correctly within regular expressions?


Take the following for example:

Person.pm

package Person;

use strict;
use warnings;
use Moose;

has 'name' => (is => 'rw', isa => 'Str');
has 'age'  => (is => 'rw', isa => 'Int');

# Make package immutable
__PACKAGE__->meta->make_immutable;

test.pl

#!/usr/bin/perl

use strict;
use warnings;
use Person;

my $person = Person->new(
    name => 'Joe',
    age  => 23,
);

my $age = 23;

# Access age the "proper" way
if ($age =~ m/$person->age()/) {
    print "MATCH 1!\n";
}

# Access age the "improper" way
if ($age =~ m/$person->{age}/) {
    print "MATCH 2!\n";
}

This code will output the following:

MATCH 2!

It seems that Perl does not parse the accessor method correctly when it is placed in a regex... What is the proper way to handle this?

I know I could just do this:

my $compare_age = $person->age();
if ($age =~ m/$compare_age/) {
    # MATCH!
}

But how can I get it to work without the extra step of storing it in a separate variable, while still going through the accessor?

1条回答
何必那么认真
2楼-- · 2019-08-08 17:20

First of all, /$compare_age/ is wrong since 23 =~ /2/ matches. Fixed:

$age =~ /^\Q$compare_age\E\z/

There is a trick to evaluate an arbitrary expression within double-quote string literals and regex literals.

$age =~ /^\Q${\( $person->age() )}\E\z/

Buy what you should be using is the following:

$age == $person->{age}
查看更多
登录 后发表回答