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