почему Perl не распознает, я хочу создать arrayRef с "split"? - PullRequest
1 голос
/ 17 мая 2019

Я хочу разделить скаляр по пробелам и сохранить результат в ArrayReference.

use strict;
use warnings;

use Data::Dumper;

my $name = 'hans georg      mustermann';
my $array = split ' ', $name;

print Dumper($array);     #$VAR1 = 3;

Так что, похоже, $array теперь является скаляром с size, полученным в результате операции split.

Когда я изменяю код на my $array = [split ' ', $name];, переменная $array теперь является ArrayReference и содержит все 3 строки.

Я просто не понимаю этого поведения.Было бы здорово, если бы кто-то мог мне это объяснить или опубликовать хорошую документацию об этих вещах, поскольку я не знаю, как искать эту тему.

Заранее спасибо

Ответы [ 3 ]

5 голосов
/ 17 мая 2019

То, что вы видите здесь, называется «контекстом».Документация об этом довольно разбросана.Вы также хотите взглянуть на этот урок о «скалярном контексте контекста списка» https://perlmaven.com/scalar-and-list-context-in-perl

Если вы присваиваете результат разделения (или любых вызовов подпрограмм) массиву, это контекст списка:

my @arr = split ' ', $name;
#=> @arr = ('hans', 'georg', 'mustermann');

То, что показывает ваш пример кода, это присвоение их скаляру - и, следовательно, он находится в «скалярном контексте».

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

Проверьте документацию по функции split: https://perldoc.pl/functions/split - который фактически определяет поведение в скалярном контексте, а также в контексте списка.

Также взгляните на документацию по всем встроенным функциям в https://perldoc.pl/functions - вы найдете определение поведенияв «списочном контексте» и «скалярном контексте» для большинства из них - хотя многие из них не возвращают «размер списков», а скорее что-то еще.

2 голосов
/ 17 мая 2019

Если вы прочитаете документацию для split(), вы найдете бит, который объясняет, что возвращает функция.

Разбивает строку EXPR на список строк и возвращает список в контексте списка или размер списка в скалярном контексте.

Вы вызываете функцию в скалярном контексте (потому что вы присваиваете результат вызова скалярной переменной), поэтому вы получаете размер списка.

Если вы хотите получить список, то вам нужно сохранить его либо в списке переменных:

my ($forename, $middlename, $surname) = split ' ', $name;

Или (чаще) в массиве:

my @name_parts = split ' ', $name;

Но на самом деле вы говорите, что хотите ссылку на массив. Это можно сделать, вызвав split() внутри конструктора анонимного массива ([ ... ]) и присвоив результат этого вызова скалярной переменной.

my $name_parts = [ split ' ', $name ];
2 голосов
/ 17 мая 2019

Это называется context .

Частичное выражение split ' ', $name оценивается как список.Частичное выражение $array = LIST приводит список к скалярному значению, а именно, подсчет количества элементов в списке.Это поведение списков по умолчанию в скалярном контексте.

Вместо этого вы должны написать @array = LIST, используя переменную массива, а не скалярную переменную, чтобы сохранить значения списка.

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