簡體   English   中英

哈希有麻煩; 第一次Perl問題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM