pdac
pdac

Reputation: 3

How to substitute a non-simple variable references in string

Consider the following code:

my $msg='My name is $person->{name}.';
my $person={ name=>'Peter', gender=>'Male' };

So I want to print $msg. I've seen examples that resolve simple variable substitutions like '$name', but I haven't seen how to resolve my problem. I tried:

print eval $msg;

but that did not work (printed nothing). How can I print My name is Peter.?

Upvotes: 0

Views: 90

Answers (4)

Dave Cross
Dave Cross

Reputation: 69244

It's always worth checking the Perl FAQ for answers to questions like this.

How can I expand variables in text strings?

Upvotes: 0

mob
mob

Reputation: 118605

When eval "does not work", it sets the special variable $@ with the error Perl encountered while evaluating the expression. In your case, that message is

syntax error at (eval 1) line 2, at EOF

because the literal text

My name is $person->{name}.

can not be parsed as Perl code. But an easy fix is to enclose that text in quotes.

my $msg='"My name is $person->{name}."';
my $person={ name=>'Peter', gender=>'Male' };

print eval $msg;

Output:

My name is Peter.

Other ways to fix this program are to send quoted text to eval:

my $msg='My name is $person->{name}.';
print eval "\"$msg\"";
print eval qq/"$msg"/;

Upvotes: 1

choroba
choroba

Reputation: 241858

You're inventing a templating system. Fortunately, it already exists: Template.

#!/usr/bin/perl
use warnings;
use strict;

use Template;

my $msg='My name is [% person.name %].';
my $person={ name=>'Peter', gender=>'Male' };

my $template = 'Template'->new;
$template->process( \$msg, { person => $person }, \ my $output );
print $output;

Upvotes: 4

Zerta
Zerta

Reputation: 175

It works when you declare the hash first. Be sure to use double quotes:

my $person={ name=>'Peter', gender=>'Male' };
my $msg="My name is $person->{name}.";

print $msg;

Upvotes: 1

Related Questions