2009-11-06 4 views
3

Я новичок в Perl. Я написал фрагмент кода для доступа к элементам массива и распечатать его на консоль:Доступ к элементам массива ссылочного массива

use strict; 
use warnings; 

my @array1 = ('20020701 00000', 'Sending Mail in Perl', 'Philip Yuson'); 
my @array2 = ('20020601', 'Manipulating Dates in Perl', 'Philip Yuson'); 
my @array3 = ('20020501', 'GUI Application for CVS', 'Philip Yuson'); 
my @main = (\@array1, \@array2, \@array3); 

my $a = $main[0]; 
print @$a; 
print @$a . "pdf"; 

Первая печать:

 
20020701 00000Sending Mail in PerlPhilip Yuson 

Но почему вторые выходы печати это?

 
3pdf 

Мне нужно, чтобы получить выход как

 
20020701 00000Sending Mail in PerlPhilip Yusonpdf 

Я не знаю, почему это дает 3pdf я томлюсь выйти из этого. Любая помощь приветствуется.

+0

(объединенное дубликат) –

+0

Ваш желаемый результат выглядит очень странный. Вы уверены, что это то, что вы хотите? Может быть, вы могли бы объяснить, почему так выглядит. –

ответ

12

Массивы являются одной из частей Perl, которые действуют по-разному в соответствии с «контекстом», что является очень важной концепцией программирования Perl. Рассмотрю это:

my @fruits = qw/apples pears bananas/; 
my $items = @fruits; 

На второй строке назначает скаляр (⇒ здесь мы имеем некоторый контекст), а с правой стороны у вас есть массив. Мы говорим, что массив здесь используется в скалярном контексте, а в скалярном контексте значением массива является количество его элементов.

Теперь к вашей проблеме: когда вы просто печатаете массив, магии не так много. Но когда вы пытаетесь добавить строку в массив с помощью оператора ., вы используете массив в скалярном контексте. Это означает, что массив вычисляет количество его элементов (3), к которому вы добавляете pdf.

Это понятно? Вы должны что-то сделать Google в «контексте Perl», что упростит вам программирование на Perl.

+0

Было бы более полезно предоставить одну или две известные полезные ссылки, а не направление их поиска. – naught101

6

Это вопрос контекста. В Perl тип данных значения является лишь частью того, что оценивается; другая половина - это контекст, в котором используется значение.

Как вы знаете, существуют три встроенных типа данных: скаляры, массивы и хеши. Существует также некоторая степень неявного литья, которая может быть выполнена между этими типами данных.

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

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

В приведенном выше примере @$a оценивает данные, вводимые в виде массива. Другая половина этой истории, хотя, это контекст, в котором оператор . работает в Чтение perldoc perlop, он говорит следующее:.

Бинарные . Объединяет две строки.

Ну, строки скалярные значения, и поэтому мы должны бросить массив @$a быть действительным в скалярном контексте, и при этом получить Спинка мощность массива. @$a содержит 3 вещи, поэтому это оценивает скалярное значение 3, которое затем превращается в строку, поэтому оператор . может работать с магией.

Надеюсь, это имеет смысл.

+2

Нет такой вещи, как «хэш-контекст» - или контекст массива (несмотря на неназванную функцию «wantarray»). Существует скалярный контекст и контекст списка, а также несколько мелких вигов, таких как булевский контекст (подмножество скаляра). – friedo

+1

У вас есть некоторые ошибки. Контексты являются 'void',' list' и 'scalar'. Контексты 'Boolean',' string' и 'numeric' являются типами скалярного контекста. Кроме того, хеши в скалярном контексте возвращают количество используемых и выделенных кодов - не количество членов, см. Perldata для получения дополнительной информации. Кроме того, когда вы упоминаете «контекст массива», это заставляет меня думать, что вы объединяете списки и массивы, есть большая разница: http://perldoc.perl.org/perlfaq4.html#What-is-the-difference-between- a-list-and-the-array% 3f – daotoad

+0

Вы оба правы. Я отредактировал свой ответ, чтобы надеяться избавиться от некоторых неточностей. –

4

print @$a . "pdf" оценивает массив в скалярном контексте, это выводит количество элементов в массиве, поэтому вы получаете 3.

Вы, вероятно, ищете что-то вроде этого:

print @$a, "pdf"; 

Оператор запятой вместо точки заставляет его в контекст списка.

14

3 - количество элементов в массиве. . заставляет массив в скалярном контексте, а затем вы получаете количество элементов вместо содержимого массива. Вы можете использовать

print "@$a pdf"; 

или

print @$a , "pdf"; 

в зависимости от того, какой выход вы хотите.

3

У меня есть ощущение, что вы действительно хотели бы это:

print "@$a.pdf", "\n"; 

То есть:

my @array1 = ('20020701 00000', 'Sending Mail in Perl', 'Philip Yuson'); 
my @array2 = ('20020601', 'Manipulating Dates in Perl', 'Philip Yuson'); 
my @array3 = ('20020501', 'GUI Application for CVS', 'Philip Yuson'); 
my @main = (\@array1, \@array2, \@array3); 

for my $x (@main) { 
    print "@$x.pdf", "\n"; 
} 

Выход:

 
20020701 00000 Sending Mail in Perl Philip Yuson.pdf 
20020601 Manipulating Dates in Perl Philip Yuson.pdf 
20020501 GUI Application for CVS Philip Yuson.pdf 
Смежные вопросы