2012-02-23 4 views
2

Как работает следующее?Печать возвращаемого значения из функции в Perl

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

, но не это:

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

Компилятор жалуется на втором фрагменте:

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

Perl обычно является довольно спокойна о принятии ярлыков при печати из комбинаций строк и переменные. $property->name призыв к классу имущества, который возвращает значение имени передается в:

sub name { 
     my ($self, $propertyName) = @_; 
     my $hash_ref = $self->{_hashref}; 
     my %properties = %$hash_ref; 
     my $property = $properties{$propertyName}; 
     return $property; 
    } 
+0

Почему downvote? – DVK

+0

В качестве дополнительной заметки ваше «подзаголовок» может быть упрощено. Избавьтесь от '% свойств и $ property' и просто получите доступ к элементу hashref напрямую:' return $ hash_ref -> {$ propertyName}; '.Или даже избавиться от '$ hash_ref' и сделать' return $ self -> {_ hashref} -> {$ propertyName}; ' – DVK

ответ

4

Поскольку

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

правильно цитировал тогда:

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

нет. Это означает:

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

Что представляет собой бессмысленное заявление.

Когда вы используете ", чтобы начать котировку, любые последующие " означает конец котировки. Вы не можете ожидать, что perl поймет, что неэкранированная двойная кавычка не предназначена для конца цитаты.

То, что вы, возможно, имел в виду,

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

Но это не будут делать то, что вы ожидаете.

Я предполагаю, что причина для интерполяции здесь заключается в том, что неудобно хранить открывающие и закрывающие кавычки. У вас есть несколько вариантов:

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"); 

Или если у вас есть список инструкций для печати, это может быть проще всего хранить их в массиве, а затем распечатать их, например:

push @props, "Property#1 is: " . $property->name("NODE_HOST"); 
push @props, "Property#2 is: " . $property->name("FOO"); 
... 
say for @props; # print them all 
+1

Вы не получите так легко интерполировать вызов функции retval. – tchrist

0

Вы получили неэкранированные кавычки внутри кавычек. NODE_HOST находится за пределами любой строки.

2

Perl делает НЕ интерполировать вызовы подпрограмм в "". Он ТОЛЬКО интерполирует скалярные и массивные переменные. Вы можете прочитать подробные сведения о правилах интерполяции на perldoc perlop.

Однако вы можете сделать скалярное выражение:

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

Однако, по правде говоря, это очень не-читаемым, и я бы посоветовал КАТЕГОРИЧЕСКИ против него. Просто выполните сверление:

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

# or  

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

Это не работает. Вам нужно '' foo $ {\ scalar func()} bar "' или '" foo @ {[func()]} bar "'. Это все известные технологии; были задокументированы с начала времени. – tchrist

+0

@tchrist - Duh. Должно было ПОСМОТРЕТЬ в поваренной книге сначала;) – DVK

+0

Нет такой вещи, как переменная списка. – ikegami