Почему Perl не делает здесь математику? - PullRequest
1 голос
/ 19 ноября 2011

У меня есть массив ссылок на хэш:

my @price = (
    {
        id    => '1',
        label => 5.00
    },
    {
        id    => '2',
        label => 7.50
    },
);

У меня также есть 2 целых числа переменных, $ diff и $ last.когда я пытаюсь перебрать массив, чтобы умножить «метку» на $diff/$last:

foreach (@price) {
    print "(($diff/$last)*$_->{label})\t";
}

, я получаю следующий вывод:

((12/30)*5.00)
((12/30)*7.50)

Я предполагаю, что это не умножение, потому чтоУ меня есть два целых числа и ссылка на хеш.Если это правильно, как я могу сделать ссылку на хеш целым числом?Как я могу заставить Perl на самом деле сделать математику и напечатать полученный продукт?

Ответы [ 4 ]

7 голосов
/ 19 ноября 2011

Это не умножение, потому что все это внутри двойных кавычек. Вам нужно сделать:

print( (($diff/$last)*$_->{label}) . "\t" );

То, как вы делаете это perl, просто интерполирует переменные и печатает их значения, потому что они заключены в кавычки. * просто рассматривается как символ для печати. Вышеприведенное делает математические вычисления, тогда . вызывает конкатенацию к "\t" (которая преобразует результат в строку).

$a = 5;
$b = 6;
print "$a + $b\n";
print $a + $b . "\n";

Выходы:

5 + 6
11

3 голосов
/ 19 ноября 2011

Вы пробовали:

foreach (@price) {
  $res = ($diff/$last)*$_->{label};
  print "$res\t";
}

Т.е. вычислить его вне кавычек, чтобы оно не интерпретировалось как строка.

0 голосов
/ 20 ноября 2011

Это не делает математику по той же причине

print "Now at 1/2 price, buy 5!\n";

не выводит

Сейчас по цене .5, купить 120

(если бы только perl использовал '!' Для обозначения 'factorial': -)

0 голосов
/ 19 ноября 2011

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

(( $diff / $last ) * $_->{label} )

- это не переменная, это выражение .Однако хеш-индекс $_->{label} также является выражением, хотя и более простым, главным образом касающимся индексации переменной для поиска значения, хранящегося в нем.Разница в том, что все дело в нескольких операциях, а не в попытке отобразить уже сохраненные данные.

Однако, поскольку логика интерполяции должна была анализировать иногда сложные выражения, вы можете интерполировать практически любое выражение - если оно «сформулировано» как индексация или разыменование.

Вы можете выполнить разыменование выражения:

print "${\(($diff/$last)*$_->{label})}\t";

Здесь вы 1) разрешаете выражение и 2) берете ссылку на его расположение в памяти, а затем 3) разыменовываете этот раздел памяти.Так что это как разыменование, только с помощью вычислений.

Существует также интерполяция литерального массива:

print "@{[ \(($diff/$last)*$_->{label}) ]}\t";

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

Опять же, они ни в коем случае не являются действительными как часть кодовой базы, которой придется жить в течение нескольких лет.Однако это дешевые и грязные уловки, которые позволяет выразительная сила Perl.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...