Alan W. Smith
Alan W. Smith

Reputation: 25445

Is there a way to use an object's attribute directly in a Perl regex replacement?

I've got a Perl Moose object that contains an attribute I'd like to use as a replacement string in a regex. The idea is to use something like:

$full_string =~ s{FIND_THIS}{$self->replace_string};

Where $self->replace_string is the Moose object's attribute to use. When run as above, it doesn't work as expected. The regex engine thinks '$self' is the variable and the '->' arrow is just a string. Instead of the value of the of the attribute, the output of the replacement ends up looking something like:

ObjectName=HASH(0x7ff458f70778)->replace_string

I know that a simple way to overcome this is to drop the string into a new variable. For example:

my $new_replace_string = $self->replace_string;
$full_string =~ s{FIND_THIS}{$new_replace_string};

My question is if there is a way to avoid creating a new variable and just use the object's attribute directly. (And, ideally without having to add a line of code.) Is this possible?

Upvotes: 1

Views: 320

Answers (3)

ikegami
ikegami

Reputation: 385917

The most straightforward way is to tell Perl the replacement expression is Perl code to evaluate. The replacement value will be the value returned by that code.

$full_string =~ s{FIND_THIS}{$self->replace_string}e;

But there exists a trick to interpolate the result of an expression into a string literal (which is what the replacement expression is).

$full_string =~ s{FIND_THIS}{${\( $self->replace_string )}/;

or

$full_string =~ s{FIND_THIS}{@{[ $self->replace_string ]}/;

The idea is create a reference and interpolate it using a dereference. In the first, the expression is evaluated in scalar context. In the latter, in list context.

Upvotes: 4

Ωmega
Ωmega

Reputation: 43673

/e evalutes right side of s/// as an expression:

$full_string =~ s/FIND_THIS/$self->replace_string/e;

Upvotes: 2

Axeman
Axeman

Reputation: 29854

Yes, you can throw the eval switch ( /e ).

$full_string =~ s{FIND_THIS}{$new_replace_string}e;

Upvotes: 1

Related Questions