我可以将 Perl 的映射与数组切片一起使用吗?

发布于 2024-08-10 09:41:29 字数 513 浏览 5 评论 0原文

我只是想缩短一行代码,将 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]

但我不断收到 Can't call method "as_trimmed_text" without a package or object引用。

是否可以做我正在尝试的事情,或者我应该坚持我目前所做的事情?

TIA

编辑:列 ->列

I'm just trying to shorten a line of code that assigns HTML::Element->as_trimmed_text from an array of HTML::Elements to some variables - pretty standard stuff like:

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

..except that there's a few more columns so it continues on over a few more lines. I had the bright idea that I could use map instead but I'm not really having much luck. I've tried variations on

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

but I keep getting Can't call method "as_trimmed_text" without a package or object reference.

Is it possible to do what I'm trying or should I just stick to what I currently have?

TIA

EDIT: column -> columns

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

Hello爱情风 2024-08-17 09:41:29

找到了:

这里有一些代码可以模拟应该发生的情况:

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()

哪些呕吐物。我会再次检查您的数组切片,并确保您没有获取实际可用索引之外的值,除此之外,请验证您是否确实正在使用该 map 处理 HTML::Element 成员。对 @columns 中的值进行快速的 Data::Dumper::Dumper 将有很大帮助。

例如,如果您随后将数组更改为包含

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

因此,请仔细检查以确保数组的内容实际上都是您尝试调用的类的所有受祝福的实例的方法.

Found it:

Here's a bit of code that emulates what should happen:

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);

This works, and works fine; I get:

Trimmed were: 'bar','baz'

But if I replace the map with this line:

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

All of a sudden I get this output:

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

This is because '3' is outside the range of valid values in @texts, so it autovivifies a new entry, and makes it undef. Then, your map does

undef->as_trimmed_output()

which barfs. I'd check your array slice again, and make sure that you aren't grabbing values outside the actual indexes available, and barring that, verify that you are actually processing HTML::Element members with that map. A quick Data::Dumper::Dumper on the values in @columns will help immensely.

For example, if you then change your array to contain

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

and try to run it, I now get your error:

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

So, double check to make sure the contents of your array are actually all blessed instances of the class you're trying to call the method of.

圈圈圆圆圈圈 2024-08-17 09:41:29

你的地图对我来说很合适。您确定第二个应该说 @columns 而不是 @column 吗?您是否启用了 strict 来捕获变量名称中的拼写错误?

Your map looks right to me. Are you sure the second one should say @columns instead of @column? Do you have strict turned on to catch typos in variable names?

倾听心声的旋律 2024-08-17 09:41:29

首先也是最重要的,如果您对地图的输出不感兴趣,则不应使用地图。 Map,像grep、sort等一样是一个过滤器。如果您不需要输出,请使用 foreach。

但你是对的,地图就是为了解决这类问题而设计的。这将给出您想要的输出,尽管它不使用数组切片。

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

Robert P 的回答更好地解释了原因原来的不起作用。

First and foremost, if you're not interested in the output of map, you shouldn't use map. Map, like grep, sort, etc is a filter. If you don't want the output, use foreach.

But you are correct, map was designed to solve exactly this kind of problem. This will give the output that you desire, although it does not use array slices.

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

Robert P's answer explains better why the original didn't work.

迷鸟归林 2024-08-17 09:41:29

您在第二个示例中使用了另一个变量 @columns,但没有使用 @column。尝试使用以下代码:

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

You're using another variable in second example @columns, but not @column. Try to use following code:

map { $_->as_trimmed_text } @column[1, 3, 5, 7, 9]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文