引用的数组的大小减少到一个元素

时间:2014-04-21 19:51:48

标签: arrays perl hash reference

亲爱的perl程序员,

我想访问这个数组

my @vsrvAttribs = qw(
  Code
  Description
  vsrv_id
  vsrv_name
  vsrv_vcpu_no
  vsrv_vmem_size
  vsrv_vdspace_alloc
  vsrv_mgmt_ip
  vsrv_os
  vsrv_virt_platf
  vsrv_owner
  vsrv_contact
  vsrv_state
);

通过一个由变量和字符串后缀组成的变量,这当然会导致像这样的错误消息

Can't use string ("@vsrvAttribs") as an ARRAY ref while "strict refs" in use at cmdbuild.pl line 262.`

因此我决定通过哈希

获取对数组的引用
my %attribs = ( vsrv => @vsrvAttribs );

这是我需要获取上述数组

内容的代码
foreach my $classTypeKey (keys %classTypes) {
  my @attribs = $attribs{$classTypeKey};
  print Dumper(\@attribs);
}

似乎我可以获得对数组@vsrvAttribs的引用,但是当我用Dumper检查数组的内容时,数组只有一个元素

$VAR1 = [
          'Code'
        ];

你知道问题出在哪里吗?

2 个答案:

答案 0 :(得分:3)

如何将数组存储在哈希中并稍后访问?

您需要通过引用存储您的数组,如下所示:

my %attribs = ( vsrv => \@vsrvAttribs );

请注意@ sigil之前的反斜杠。这告诉perl你想要一个对数组的引用。

然后,当访问存储在$attribs{vsrv}中的数组时,您需要将其视为引用而不是数组。你会做这样的事情:

foreach my $classTypeKey (keys %classTypes) {
  # make a copy of the array by dereferencing
  my @attribs = @{ $attribs{$classTypeKey} };

  # OR just use the array reference if profiling shows performance issues:
  my $attribs = $attribs{$classTypeKey}

  # these will show the same thing if you haven't done anything to @attribs
  # in the interim
  print Dumper(\@attribs);
  print Dumper($attribs);
}

为什么你只获得一个值,数组的其余部分在哪里?

@vsrvAttribs中的遗失值未丢失,它们被分配为%attribs本身的键和值。在完成作业后尝试添加以下内容,您将自己看到它:

my %attribs = ( vsrv => @vsrvAttribs );
print Dumper(\%attribs);

你会看到这样的输出:

$VAR1 = {
          'vsrv_contact' => 'vsrv_state',
          'vsrv_virt_platf' => 'vsrv_owner',
          'vsrv' => 'Code',
          'vsrv_name' => 'vsrv_vcpu_no',
          'vsrv_mgmt_ip' => 'vsrv_os',
          'Description' => 'vsrv_id',
          'vsrv_vmem_size' => 'vsrv_vdspace_alloc'
        };

这是因为perl通过将内容@vsrvAttribs扩展为列表文字()的多个参数来解释您的作业:

my %attribs = (
  # your key  => first value from array
  vsrv        => 'Code',

  # subsequent values of the array
  Description => 'vsrv_id',
  vsrv_name   => 'vsrv_vcpu_no',
  vsrv_vmem_size  => 'vsrv_vdspace_alloc',
  vsrv_mgmt_ip    => 'vsrv_os',
  vsrv_virt_platf => 'vsrv_owner',
  vsrv_contact    => 'vsrv_state',
);

这在perl中是合法的,并且有理由你可能想要这样做但在你的情况下它不是你想要的。

顺便提一下,如果你的数组中有偶数个元素,那么你会被警告perl正在做你可能不想要的事情。你的13个元素刷新哈希键“vsrv”使得14是偶数。 Perl将采用具有偶数元素的任何列表,并愉快地将其变为哈希。如果你的数组有15个元素的另一个元素,那么你会得到一个警告:Odd number of elements in hash assignment at foo.pl line 28.

有关详情,请参阅perldoc perlreftut中的“制作参考资料”和“使用参考资料”。

答案 1 :(得分:3)

如果在哈希定义中使用裸数组,如

my %attribs = ( vsrv => @vsrv_attribs )

数组被扩展并用作键/值对,因此您将获得

我的%attribs =(      vsrv => '码',      Description => 'vsrv_id',      vsrv_name => 'vsrv_vcpu_no',      vsrv_vmem_size => 'vsrv_vdspace_alloc',      ...   )

Perl哈希元素的只能是标量值,所以如果你想要一个值数组,你必须得到一个引用,如下所示

在除了全局变量之外的任何事物中使用Perl标识符中的大写字母也是一个坏主意,例如包名称。本地名称是传统的小写字母数字加下划线,因此$class_type_key代替$classTypeKey

use strict;
use warnings;

use Data::Dumper;

my @vsrv_attribs = qw(
  Code
  Description
  vsrv_id
  vsrv_name
  vsrv_vcpu_no
  vsrv_vmem_size
  vsrv_vdspace_alloc
  vsrv_mgmt_ip
  vsrv_os
  vsrv_virt_platf
  vsrv_owner
  vsrv_contact
  vsrv_state
);

my %attribs = (
  vsrc => \@vsrv_attribs,
);


for my $class_type_key (keys %attribs) {
  my $attribs = $attribs{$class_type_key};
  print Dumper $attribs;
}

<强>输出

$VAR1 = [
          'Code',
          'Description',
          'vsrv_id',
          'vsrv_name',
          'vsrv_vcpu_no',
          'vsrv_vmem_size',
          'vsrv_vdspace_alloc',
          'vsrv_mgmt_ip',
          'vsrv_os',
          'vsrv_virt_platf',
          'vsrv_owner',
          'vsrv_contact',
          'vsrv_state'
        ];