2

How come the following works?

    print "Property is :" . $property->name("NODE_HOST") . "\n";

but not this:

    print "Property is : $property->$name("NODE_HOST")\n";

The compiler complains about the second snippet:

    Bareword found where operator expected at ./testProperties.pl line 11, near ""Property is : $property->$name("NODE_HOST"
    (Missing operator before NODE_HOST?)

Perl is normally pretty easy-going about taking shortcuts when printing out combinations of strings and variables. $property->name is a call to a class Property which returns the value of the name passed in:

    sub name {
       my ( $self, $propertyName ) = @_;
       my $hash_ref = $self->{_hashref};
       my %properties = %$hash_ref;
       my $property = $properties{$propertyName};
       return $property;
    }
1
  • As a side note, your sub name can be simplified. Get rid of %properties and $property and just access hashref element directly: return $hash_ref->{$propertyName};. Or even get rid of $hash_ref and do return $self->{_hashref}->{$propertyName}; Commented Feb 24, 2012 at 0:04

3 Answers 3

5

Because

print "Property is :" . $property->name("NODE_HOST") . "\n";

is properly quoted whereas:

print "Property is : $property->$name("NODE_HOST")\n";

is not. It means:

print "Property is : $property->$name("
NODE_HOST
")\n";

Which is a nonsensical statement.

When you use " to start a quote, any following " means end of quote. You can't expect perl to understand that a non-escaped double quote is not intended as end of quote.

What you might have meant is

print "Property is : $property->$name(\"NODE_HOST\")\n";

But that wont do what you expect.

I assume that the reason for trying to interpolate here is that it is awkward to keep opening and closing quotes. You have some options:

printf "Property is: %s\n", $property->name("NODE_HOST");

$name = $property->name("NODE_HOST");
print "Property is: $name\n";

use v5.10; # to enable say()
say "Property is: ", $property->name("NODE_HOST");

Or if you have a list of statements to print, it might be easiest to store them in an array, and then print them, e.g.:

push @props, "Property#1 is: " . $property->name("NODE_HOST");
push @props, "Property#2 is: " . $property->name("FOO");
...
say for @props;   # print them all
Sign up to request clarification or add additional context in comments.

1 Comment

You won’t get a function call retval interpolated that easily.
3

Perl does NOT interpolate subroutine calls in "". It ONLY interpolates scalar and array variables. You can read the gory details of interpolation rules on perldoc perlop.

You CAN however do a scalar expression:

print "Property is : ${ \( $property->name('NODE_HOST') ) }\n";

However, truth be told, it's highly un-readable and I would advise STRONGLY against it. Just do the boring:

my $property_name = $property->name('NODE_HOST');
print "Property is : $property_name\n";

# or    

print "Property is :" . $property->name("NODE_HOST") . "\n";

3 Comments

That doesn't quite work. You need "foo ${ \scalar func() } bar" or "foo @{ [ func() ] } bar". This is all known tech; been documented since the beginning of time.
@tchrist - Duh. Should have actually LOOKED at the cookbook first ;)
No such thing as a list variable.
0

You've got unescaped quotes inside quotes. NODE_HOST is outside any string.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.