2009-11-05 98 views
2

我只是想缩短线路的指派HTML ::元素 - > as_trimmed_text从HTML ::元素的数组到一些变量的代码 - 非常标准的东西,如:我可以将Perl映射与数组切片一起使用吗?

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

..except那还有几列,所以它会继续多行。我有一个好主意,我可以用地图来代替,但我并没有太多的运气。我试过的变化上

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

,但我不断收到无法调用“as_trimmed_text”没有包装或对象引用。

是否有可能做我正在尝试,或者我应该坚持我现在拥有的?

TIA

编辑:列 - >列

+2

目前看起来您正在使用不同的变量:第一个示例为“@ column”,第二个为“@ columns”。但是使用“地图”的想法很好 – 2009-11-05 22:25:27

+0

这是行不通的吗? 'map {$ columns [$ _] - > as_trimmed_text} 1,3,5,7,9' – 2009-11-05 22:31:43

+1

你可能需要在你正在做的事情中添加更多的代码;这对我来说是正确的。 – 2009-11-05 22:31:56

回答

1

首先,如果您对地图输出不感兴趣,则不应使用地图。地图,像grep,排序等是一个过滤器。如果你不想输出,使用foreach。

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

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

Robert P's answer更好地解释了为什么原来没有工作。

+0

-1。这个答案只有真实的陈述,它有有效的代码,但它没有解决这个问题,这个问题是关于使用具有**数组slice **的'map'的问题。它也没有提供原始代码错误的解释。 – 2009-11-05 23:49:47

+1

我想你在技术上是正确的。我更关心的是以最正确的方式为他的问题提供解决方案,而不是回答发布的确切问题。 由于数组切片被perl视为不可变列表,因此使用map对其进行内联修改(您不应该这样做)将是错误的解决方法。 我会修改我的答案,使其更具表现力。 – Bob 2009-11-06 00:13:20

+1

问题中的代码不会修改任何内容,并且它对数组切片的使用没有任何问题...... – hobbs 2009-11-06 04:52:06

5

map看起来我的权利。你确定第二个应该说@columns而不是@column?你是否打开strict来捕捉变量名中的拼写错误?

+0

形而上学的+1因为我仍然没有upvotes。诅咒! – 2009-11-05 22:26:41

+4

'使用严格的岩石' – 2009-11-05 22:29:23

+2

什么是'严格的岩石'? – pavium 2009-11-05 22:31:48

1

您在第二个示例@columns中使用另一个变量,但不是@column。尝试使用下面的代码:

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

发现:

下面是一些代码,它模拟什么应该发生:

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

哪个barfs。我会再次检查你的数组片段,并确保你没有获取可用实际索引之外的值,并且除此之外,请验证你是否正在处理具有该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 

所以,仔细检查,以确保内容你的数组实际上是你试图调用方法的类的所有祝福实例。

+0

像这样的迟到(可能)正确答案会让我很伤心,因为我已经失去了upvotes。 – 2009-11-05 22:45:37

+0

@Chris:你说了很多(你希望你可以upvote等)。为什么不在第二天简单地回来,并upvote? – Telemachus 2009-11-06 01:20:36

+0

这是最可能的答案,排除错字假设:) – hobbs 2009-11-06 04:53:29

相关问题