perl中的(@{$value{$value}})是什么?

perl中的(@{$value{$value}})是什么?,perl,Perl,我已经花了几个星期的时间试图让perl程序正常工作。这是别人写的,从那以后数据源就被改变了。我花了数周时间逐行搜索并做教程。我被卡住了。代码显示{$Routings{$code}}它有一个值列表[$ProcessID,$Setup,$Process],但是当foreach({$Routings{$code}}}{my$ProcessCodeID=@$\u0];}它似乎没有返回数据时,代码就在代码的底部。如果有人能帮我打印$ProcessCodeID,这样我就可以跟踪数据了,那将非常有帮助 另外,

我已经花了几个星期的时间试图让perl程序正常工作。这是别人写的,从那以后数据源就被改变了。我花了数周时间逐行搜索并做教程。我被卡住了。代码显示
{$Routings{$code}}
它有一个值列表
[$ProcessID,$Setup,$Process]
,但是当
foreach({$Routings{$code}}}{my$ProcessCodeID=@$\u0];}
它似乎没有返回数据时,代码就在代码的底部。如果有人能帮我打印$ProcessCodeID,这样我就可以跟踪数据了,那将非常有帮助

另外,如果你能解释一下
@{$value{$key}}
代表了什么,那也会很有帮助

谢谢你

%Routings = ();
my $dbh = DBI-> connect('dbi:ODBC:SQL')
    or die "Couldn't open Databaxe: $DBI::errstr;  stopped";

my $query= $dbh->prepare("SELECT Code, Setup, Process, ProcessID FROM ROUTING");

$query->execute() or die "Couldn't execute statement: $DBI::errstr; stopped";

while ( my ($Code, $setup, $process, $processid) = $query->fetchrow_array() ){
    push ( @{ $Routings{$Code} }, [ $ProcessID, $Setup, $Process ] );
}

foreach ( @{ $Routings{$Code} } ) {
    my $ProcessCodeID = @$_[0];
    my $SetupMins = @$_[1];
    my $ProcessMins = @$_[2];
}
它实际上并不是试图返回数据——它只是用数据创建变量,然后立即对数据不做任何处理。试试这个:

foreach ( @{ $Routings{$Code} } ) {
    my $ProcessCodeID = @$_[0];
    my $SetupMins = @$_[1];
    my $ProcessMins = @$_[2];
    print "$Code: $ProcessCodeID, $SetupMins, $ProcessMins\n";
}
除非在循环中使用变量,否则没有太多意义

复杂的ish
@{$foo{$bar}
构造告诉Perl将
$foo{$bar}
视为一个数组
$foo{$bar}
是一种哈希查找。(请参阅顶部的
%Routings=();
,它声明并初始化哈希。)

Perl确实很简洁,但这类事情足以让我决定用Ruby等较新语言编写新代码。这段代码在Ruby中可能也没有太好的表现,精通这两种语言的人也不会真的在意,但您可能希望借此机会重新编写需要维护的工具。

这段代码将“路由记录”按“代码”分组


%Routings
是散列。它由“代码”输入。每个值都是对数组的引用。这些数组由
push(@{$Routings{$code}},
)自动激活,它是
push(@{$Routings{$code}/=[]},
的缩写

这些数组中的每一个都包含许多“记录”。每个“记录”是对三个元素(“进程id”、“设置”和“进程”)数组的引用。它们由
[$ProcessID、$setup、$process]
创建

转储看起来像:

{
   $code0 => [
      [ $ProcessID0, $setup0, $Process0 ],
      [ $ProcessID2, $setup2, $Process2 ],
      ...
   ],
   $code1 => [
      [ $ProcessID1, $setup1, $Process1 ],
      [ $ProcessID5, $setup5, $Process5 ],
      ...
   ],
   $code2 => [
      [ $ProcessID3, $setup3, $Process3 ],
      [ $ProcessID4, $setup4, $Process4 ],
      ...
   ],
   ...
}

如果
$code
有一个有意义的值-您没有显示该值-
$Routings{$code}
将计算为这些数组引用之一。从上面的示例中

[
   [ $ProcessID0, $setup0, $Process0 ],
   [ $ProcessID2, $setup2, $Process2 ],
   ...
],
@{…}
向Perl指示您希望解除对该引用的限制。换句话说,它告诉Perl您对数组本身感兴趣

当您将数组传递给foreach时,它会在其元素上迭代。因此,第一次通过循环时,
$\uuuz
将保存以下数组引用:

[ $ProcessID0, $setup0, $Process0 ],
$employee_reference = $employee_list[0];
%employee_hash      = %$employee_reference;
print "Employee name is $employee_hash{FIRST} $employee_hash{LAST}\n";
第二次,

[ $ProcessID2, $setup2, $Process2 ],
等等

${$}[0]
(缩写为
${$}[0]
,这是一个使用不正确的
${$}[0]
,当
${$}[0]
)获取引用数组的第一个元素(
$ProcessID0
)时可读性更高。类似地,
${code>$[1]
$[2]
获取
$setup0
$Process0


当然,然后你继续对数据不做任何处理。你可能是有意的

foreach ( @{ $Routings{$Code} } ) {
    my $ProcessCodeID = ${$_}[0];
    my $SetupMins     = ${$_}[1];
    my $ProcessMins   = ${$_}[2];
    print("$ProcessCodeID ,$SetupMins, $processMins\n");
}
清理:

foreach ( @{ $Routings{$Code} } ) {
    my $ProcessCodeID = $_->[0];
    my $SetupMins     = $_->[1];
    my $ProcessMins   = $_->[2];
    print("$ProcessCodeID, $SetupMins, $processMins\n");
}
再清理一些:

for ( @{ $Routings{$Code} } ) {
    my ($ProcessCodeID, $SetupMins, $ProcessMins) = @$_;
    print("$ProcessCodeID, $SetupMins, $processMins\n");
}
从技术上讲,你甚至可以做到

for ( @{ $Routings{$Code} } ) {
    print(join(', ', @$_), "\n");
}


首先,重要的是在程序开始时
使用strict
使用warnings
,并在第一次使用变量时声明所有变量。这将导致Perl生成一些非常有用的消息,这些消息将揭示许多容易被忽略的简单错误

例如,您将变量
$setup
$process
$processid
分配到数组中,然后将
$setup
$process
$processid
推送到数组中。Perl标识符区分大小写,因此这是三个不同的变量,并且在这一点。
use strict
可能会打印一个编译错误,说明未声明
$ProcessID
等。(如果您有选择,最好对此类本地标识符使用小写加下划线。经验丰富的Perl程序员将感谢您。)

您应该尝试使用它,它将显示像这样的复杂嵌套Perl数据结构的内容和结构

print Dumper \%Routings
它将以匿名哈希的形式显示
%Routings
的内容

散列的每个元素
$Routings{$code}
的值是一个列表(对数组的引用),其中包含与该代码值相对应的所有ProcessID、Setup和Process集合。(我假设
code
列是非唯一的,否则数据结构将比需要的更复杂。)因此,给定的
$code
的第一组三个值位于
$Routings{$code}[0]
,该组的
ProcessID
$Routings{$code}[0][0]

对于
foreach
循环,没有代码为
$code
赋值,您可能希望循环
%Routings
散列的所有键

每次
foreach
循环
$
被设置为对当前
$code
的每个三元组值的引用。这意味着
@$
是一个三元素数组,但它应该使用
$->[0]
等来索引,而不是
@$[0]
这是一个单元素数组切片,编码实践很差。这里使用默认的
$\uu
使代码更加模糊,下面我使用命名变量对其进行了说明

下面的代码修复了我看到的问题。如果需要进一步帮助,请回来

use strict;
use warnings;

use DBI;

my %Routings;

my $dbh = DBI-> connect('dbi:ODBC:SQL')
    or die "Couldn't open Databaxe: $DBI::errstr;  stopped";

my $query= $dbh->prepare("SELECT Code, Setup, Process, ProcessID FROM ROUTING");

$query->execute or die "Couldn't execute statement: $DBI::errstr; stopped";

while ( my ($Code, $Setup, $Process, $ProcessID) = $query->fetchrow_array ){
  push @{ $Routings{$Code} }, [ $ProcessID, $Setup, $Process ];
}

for my $Code (keys %Routings) {
  foreach my $triplet ( @{ $Routings{$Code} } ) {
    my $ProcessCodeID = $triplet->[0];
    my $SetupMins = $triplet->[1];
    my $ProcessMins = $triplet->[2];
    print "$Code => ($ProcessCodeID, $SetupMins, $ProcessMins)\n";
  }
}
请注意,
foreach
循环中的赋值可以通过一次性执行而变得更清晰、更简洁
my ($ProcessCodeID, $SetupMins, $ProcessMins) = @$triplet;
$employee_list[0] = "Bob";
$employee_list[1] = "Carol";
$employee_list[2] = "Ted";
$employee_list[3] = "Alice";
$employee{FIRST}  = "Bob";
$employee{LAST}   = "Jones";
$employee{PAY}    = "1400";
$employee{PHONE}  = "1234";
$employee_list[0] = \%employee;
$employee_reference = $employee_list[0];
%employee_hash      = %$employee_reference;
print "Employee name is $employee_hash{FIRST} $employee_hash{LAST}\n";
%employee_hash      = %{ $employee_list[0] };
print "Employee name is $employee_hash{FIRST} $employee_hash{LAST}\n";
print "Employee name is "
   . ${ $employee_list[0] }{FIRST} . " "
   . ${ $employee_list[0] }{LAST} . "\n";
print "Employee name is " 
  . $employee_list[0]->{FIRST} . " " 
  . $employee_list[0]->{LAST} . "\n";
$employee_list[0] = { LAST => "Jones", FIRST => "Bob",
    SALARY => 1400, PHONE => "1234" }
$employee_list[0]->{NAME}->{FIRST} = "Bob";
$employee_list[0]->{NAME}->{LAST}  = "Jones";
$employee_list[0]->{ADDRESS}->[0]->{TYPE} = "Business";
$employee_list[0]->{ADDRESS}->[0]->{STREET}->[0] = "123 Mockingbird Lane";
$employee_list[0]->{ADDRESS}->[0]->{STREET}->[1] = "Tower 2";
$employee_list[0]->{ADDRESS}->[0]->{CITY} = "Beantown";
$employee_list[0]->{ADDRESS}->[0]->{STATE} = "MA";
use Data::Dumper;

[...]

print "Employee Dump: " . Dumper \@employee . "\n";
print Dumper $value{$key} . "\n";
%Routings = ();
my $dbh = DBI->connect('dbi:ODBC:SQL')
    or die "Couldn't open Databaxe: $DBI::errstr;  stopped";
$employee = Person::Employee->new;
$employee->first_name( "Bob" );
my $query= $dbh->prepare("SELECT Code, Setup, Process, ProcessID FROM ROUTING");
$query->execute() or die "Couldn't execute statement: $DBI::errstr; stopped";
while ( my ($Code, $setup, $process, $processid) = $query->fetchrow_array() ){
    push ( @{ $Routings{$Code} }, [ $ProcessID, $Setup, $Process ] );
}
while ( my @fetched_row = $query->fetchrow_array() ){
    my ($Code, $setup, $process, $processid) = @fetched_row;
    push ( @{ $Routings{$Code} }, [ $ProcessID, $Setup, $Process ] );
}
my @temp_array = ($ProcessID, $Setup, $Process);
my @temp_routing_array = @{ $Routings{Code} }; #Dereferencing the $Routing{$Code} array
push( @temp_routing_array, \@temp_array );     #Pushing a reference into my array
$Routing{$Code} = \@temp_routing_array;   #Creating a reference again
foreach ( @{ $Routings{$Code} } ) {
    my $ProcessCodeID = @$_[0];
    my $SetupMins = @$_[1];
    my $ProcessMins = @$_[2];
}
my @routing_code_ref_array = @{ $Routings{$Code} };

foreach my $routing_array_ref (@routing_code_ref_array) {
    my @routing_array = @{ $routing_array_ref };

    my $ProcessCodeID  = $routing_array[0];
    my $SetupMins      = $routing_array[1];
    my $ProcessMins    = $routing_array[2];
}