[英]Having trouble with hashes; first time Perl questions
如果這個問題太含糊,我真的很抱歉。 我將盡力嘗試總結我的問題。 這是我第一次搞砸Perl,我想我已經快要掌握它了。
我有一個哈希,用於存儲有關從Asterisk收到的呼叫的信息。
每個調用都應該在哈希中有一個條目,鍵是唯一的ID(我知道這可能是不好的做法,但是鍵會在腳本結尾處被銷毀,因此我不必擔心重復)。
當我從Asterisk獲取數據時,我需要不斷將新數據附加到hash元素上,然后在某些時候將結果打印到TCP套接字。
這就是我所擁有的。 我的問題是我似乎無法將新數據追加到同一哈希鍵。
請原諒我的業余愛好; 格式化/最佳做法/任何方面的任何幫助,我們深表感謝!
use Asterisk::AMI;
use IO::Socket;
use strict;
use warnings;
use Data::Dumper;
my %call;
my $sock = new IO::Socket::INET(
PeerAddr => '127.0.0.1',
PeerPort => '1234',
Proto => 'tcp',
);
die "Could not create socket: $!\n" unless $sock;
my $astman = Asterisk::AMI->new(
PeerAddr => '127.0.0.1',
PeerPort => '5038',
Username => 'user',
Secret => 'secret',
Events => 'on',
Handlers => {
#default => \&eventhandler,
Dial => \&ringcheck,
Bridge => \&bridgecheck,
Newchannel => \&newchannel
}
);
die "Unable to connect to asterisk" unless ($astman);
# Default event handler
sub eventhandler {
my ($ami, $event) = @_;
print 'Got Event: ', $event->{'Event'}, "\r\n";
}
sub newchannel {
my ($ami, $event) = @_;
if ($event->{'Context'} eq "from-trunk") {
$call = $event->{'Uniqueid'} => {
caller_name => $event->{'CallerIDName'},
caller_number => $event->{'CallerIDNum'},
dnis => $event->{'Exten'}
};
}
}
sub ringcheck {
my ($ami, $event) = @_;
if ($event->{'SubEvent'} eq "Begin") {
$call = $event->{'UniqueID'} => {
system_extension => $event->{'Dialstring'},
dest_uniqueid => $event->{'DestUniqueID'}
};
print $sock "R|", $call{ $event->{'UniqueID'} }{'caller_name'}, "|",
$call{ $event->{'UniqueID'} }{'caller_number'}, "|",
$call{ $event->{'UniqueID'} }{'system_extension'}, "||",
$call{ $event->{'UniqueID'} }{'dnis'}, "\r\n";
}
}
sub bridgecheck {
my ($ami, $event) = @_;
if ($event->{'Bridgestate'} eq "Link") {
# Call has started
print $sock "A|", $call{ $event->{'UniqueID'} }{'caller_name'}, "|",
$call{ $event->{'UniqueID'} }{'caller_number'}, "|",
$call{ $event->{'UniqueID'} }{'system_extension'}, "||",
$call{ $event->{'UniqueID'} }{'dnis'}, "\r\n";
}
elsif ($event->{'Bridgestate'} eq "Unlink") {
# Call has ended
}
}
EV::loop
需要明確的是,問題是我應該如何追加新的數據,在ringcheck
子程序,例如,在%call
所創建的哈希newchannel
子程序?
由於您沒有聲明$call
您必須從use strict
那里收到一條錯誤消息。 如果您告訴我們,那將會有很大幫助。
請使用最小的縮進:通常使用四個或更少的空格,而我使用兩個。 大的縮進使代碼難以遵循
即使在Windows上,也不要以"\\r\\n"
終止輸出行。 Perl處理了所有這些,您應該在任何平台上只打印"\\n"
換行符
哈希%call
是與標量$call
完全獨立的變量,因此分配給$call
根本不會影響您的哈希。 如果strict
到位,您會看到錯誤,因為尚未定義$call
要分配給哈希元素,請使用$hash{$key}
。 可以將其視為一個數組元素,但是哈希值不是整數,而是由字符串索引的。 如果要使用常量作為哈希鍵,則可以省略引號,因此$call{'caller_name'}
與$call{caller_name}
現在來看一下ringcheck
,如果將$event->{UniqueID}
的值復制到一個標量變量中,而不是在需要的地方都使用相同的哈希元素,那么它將使您的代碼更加簡潔和易於理解。 您可以使用哈希引用$call{$unique_id}
我已將您的代碼更改為可能有效的方法,或者至少將對您有所幫助。 我使用過printf
來將格式與數據分開,並使其更具可讀性。
sub ringcheck {
my ($ami, $event) = @_;
if ($event->{SubEvent} eq 'Begin') {
my $unique_id = $event->{UniqueID};
my $this_call = $call{$unique_id};
$this_call->{system_extension} = $event->{Dialstring};
$this_call->{dest_uniqueid} = $event->{DestUniqueID};
printf $sock "R|%s|%s|%s||%s\n",
$this_call->{caller_name},
$this_call->{caller_number},
$this_call->{system_extension},
$this_call->{dnis};
}
}
您使用了錯誤的運算符進行分配。 =>
為同義詞,
與引用其左手操作數的附加效果(除非它是一個變量。)
我對星號一無所知,但您可能想要:
$event->{'UniqueID'} = {
system_extension => $event->{'Dialstring'},
dest_uniqueid => $event->{'DestUniqueID'}
};
不過,我不確定您要使用$call
做什么。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.