Могу ли я использовать карту Perl с фрагментом массива?

StackOverflow https://stackoverflow.com/questions/1684059

  •  18-09-2019
  •  | 
  •  

Вопрос

Я просто пытаюсь сократить строку кода, которая присваивает HTML::Element->as_trimmed_text из массива HTML::Elements некоторым переменным - довольно стандартные вещи, такие как:

my ($var1, var2) = ($columns[1]->as_trimmed_text, $columns[2]->as_trimmed_text);

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

map { $_->as_trimmed_text } @columns[1, 3, 5, 7, 9]

но я продолжаю получать сообщение «Невозможно вызвать метод as_trimmed_text» без ссылки на пакет или объект.

Возможно ли сделать то, что я пытаюсь, или мне следует просто придерживаться того, что у меня есть сейчас?

ТИА

РЕДАКТИРОВАТЬ:столбец -> столбцы

Это было полезно?

Решение

Прежде всего, если вас не интересует вывод карты, вам не следует использовать карту.Карта, как и grep, sort и т. д., является фильтром.Если вам не нужен вывод, используйте foreach.

Но вы правы, карта была создана для решения именно такой проблемы.Это даст желаемый результат, хотя срезы массива не используются.

@trimmed_columns = map { $column[$_]->as_trimmed_text } (1, 3, 5, 7, 9);

Ответ Роберта П. лучше объясняет, почему оригинал не сработал.

Другие советы

Нашел:

Вот немного кода, который имитирует то, что должен случаться:

use strict;
use warnings;

package Text;

sub new
{
   my $class = shift;
   my $text = shift;
   return bless { TEXT => $text }, $class;
}

sub as_trimmed_text
{
   my $self = shift;
   my $text = $self->{TEXT};
   $text =~ s/^\s*(.*?)\s*$/$1/;
   return $text;
}

package main;

my @texts = ( Text->new(' foo '), Text->new(' bar '), Text->new(' baz '));

my @trimmed = map { $_->as_trimmed_text() } @texts[1, 2];

print "Trimmed were: ", join(',', map { "'$_'" } @trimmed);

Это работает, и работает отлично;Я получил:

Trimmed were: 'bar','baz'

Но если я заменю карту этой строкой:

my @trimmed = map { $_->as_trimmed_text() } @texts[2, 3];

Внезапно я получаю этот вывод:

Can't call method "as_trimmed_text" on an undefined value

Это связано с тем, что «3» находится за пределами диапазона допустимых значений в @texts, поэтому он автоматически оживляет новую запись и делает ее undef.Затем ваша карта делает

undef->as_trimmed_output()

который блюет.Я бы еще раз проверил ваш фрагмент массива и убедился, что вы не захватываете значения за пределами фактических доступных индексов, и, исключая это, убедитесь, что вы действительно обрабатываете элементы HTML::Element с этим map.Быстрый Data::Dumper::Dumper о ценностях в @columns очень поможет.

Например, если вы затем измените свой массив, чтобы он содержал

my @texts = ( Text->new(' foo '), Text->new(' bar '), ' baz ');

и попытайтесь запустить его, теперь я получаю вашу ошибку:

Can't call method "as_trimmed_text" without a package or object reference at map.pl

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

Твой map мне кажется, что это правильно.Ты уверен, что второй должен сказать @columns вместо @column?У вас есть strict включен для обнаружения опечаток в именах переменных?

Вы используете другую переменную во втором примере @columns, но нет @column.Попробуйте использовать следующий код:

map { $_->as_trimmed_text } @column[1, 3, 5, 7, 9]
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top