Как печатать переменные в Perl

У меня есть код, который выглядит как

my ($ids,$nIds);
while (<myFile>){
    chomp;
    $ids.= $_ . " ";
    $nIds++;
}

Это должно конкатенировать каждую строку в моем myFile, а nIds должно быть моим числом строк. Как распечатать мои $ids и $nIds?

Я попробовал просто print $ids, но Perl жалуется.

my ($ids, $nIds)

- список, не так ли? С двумя элементами?

Ответы

Ответ 1

print "Number of lines: $nids\n";
print "Content: $ids\n";

Как жаловался Perl? print $ids должен работать, хотя вы, вероятно, хотите использовать новую строку в конце, либо явно с помощью print, как указано выше, либо неявно, используя say или -l/$\.

Если вы хотите интерполировать переменную в строке и иметь что-то сразу после нее, которая будет выглядеть как часть переменной, но не является, добавьте имя переменной в {}:

print "foo${ids}bar";

Ответ 2

При задании вопроса всегда следует включать все соответствующие коды. В этом случае утверждение печати, которое является центром вашего вопроса. Заявление о печати, вероятно, является наиболее важной частью информации. Вторая наиболее важная часть информации - это ошибка, которую вы также не включили. В следующий раз включите оба этих файла.

print $ids должно быть довольно жестким выражением, чтобы испортить, но это возможно. Возможные причины:

  • $ids - undefined. Предоставляет предупреждение undefined value in print
  • $ids выходит за рамки. С помощью use strict выдается фатальное предупреждение Global variable $ids needs explicit package name, а в противном случае undefined предупреждение сверху.
  • Вы забыли полуточку в конце строка.
  • Вы пытались сделать print $ids $nIds, в этом случае perl считает, что $ids должен быть файловым дескриптором, и вы получаете ошибку, например print to unopened filehandle.

Разъяснения

1: Не должно быть. Это может произойти, если вы сделаете что-то вроде этого (если вы не используете strict):

my $var;
while (<>) {
    $Var .= $_;
}
print $var;

Дает предупреждение для значения undefined, потому что $Var и $Var - две разные переменные.

2: Возможно, если вы сделаете что-то вроде этого:

if ($something) {
    my $var = "something happened!";
}
print $var;

my объявляет переменную внутри текущего блока. Вне блока он выходит за рамки.

3: достаточно простая, распространенная ошибка, легко фиксируется. Легче определить с помощью use warnings.

4: Также распространенная ошибка. Существует несколько способов правильной печати двух переменных в одном и том же выражении print:

print "$var1 $var2";  # concatenation inside a double quoted string
print $var1 . $var2;  # concatenation
print $var1, $var2;   # supplying print with a list of args

Наконец, некоторые подсказки волшебства perl для вас:

use strict;
use warnings;

# open with explicit direction '<', check the return value
# to make sure open succeeded. Using a lexical filehandle.
open my $fh, '<', 'file.txt' or die $!;

# read the whole file into an array and
# chomp all the lines at once
chomp(my @file = <$fh>);
close $fh;

my $ids  = join(' ', @file);
my $nIds = scalar @file;
print "Number of lines: $nIds\n";
print "Text:\n$ids\n";

Чтение всего файла в массив подходит только для небольших файлов, в противном случае он использует много памяти. Как правило, предпочтительным является линейная строка.

Варианты:

  • print "@file" эквивалентен $ids = join(' ',@file); print $ids;
  • $#file вернет последний индекс в @file. Поскольку массивы обычно начинаются с 0, $#file + 1 эквивалентно scalar @file.

Вы также можете сделать:

my $ids;
do {
    local $/;
    $ids = <$fh>;
}

Временно "выключая" $/ разделитель входных записей, т.е. новая строка, вы сделаете <$fh>, чтобы вернуть весь файл. Что действительно делает <$fh>, пока не найдет $/, а затем вернет эту строку. Обратите внимание, что это сохранит символы новой строки в $ids.

Пошаговое решение:

open my $fh, '<', 'file.txt' or die $!; # btw, $! contains the most recent error
my $ids;
while (<$fh>) {
    chomp;
    $ids .= "$_ "; # concatenate with string
}
my $nIds = $.; # $. is Current line number for the last filehandle accessed.

Ответ 3

Как распечатать мои $ids и $nIds?
print "$ids\n";
print "$nIds\n";
Я попробовал просто print $ids, но Perl жалуется.

Жалуется на что? Неинициализированная стоимость? Возможно, ваш цикл не был введен из-за ошибки открытия файла. Обязательно проверьте, вернула ли ошибка open, и убедитесь, что вы используете use strict; use warnings;.

my ($ids, $nIds) - это список, не так ли? С двумя элементами?

Это вызов (очень специальный). $ids,$nIds - это список с двумя элементами.