2011-11-18 23 views
1

我使用AnyEvent :: Twitter :: Stream模塊來獲取推文。最終,我試圖將推文打印到文件中,但我無法(我認爲)將推文作爲JSON對象。我的代碼如下:如何使用AnyEvent在perl中輸出JSON對象:: Twitter :: Stream

#!/Applications/XAMPP/xamppfiles/bin/perl 

use AnyEvent::Twitter::Stream; 
    my $done = AnyEvent->condvar; 

BEGIN { 
    use Exporter; 
    our @ISA = qw(Exporter); 
    our @EXPORT = qw{ 
     &init 
    }; 
} 

sub print_tweet { 
    my $tweet = shift; 
    print $tweet; 
} 


    # receive updates from @following_ids 
    my $listener = AnyEvent::Twitter::Stream->new(
     username => XXXXXX 
     password => XXXXXX 
     method => 'sample', # "firehose" for everything, "sample" for sample timeline 
     decode_json => 1, 
     on_tweet => sub { 
      my $tweet = shift; 
      print_tweet($tweet); 
     }, 
     on_keepalive => sub { 
      warn "ping\n"; 
     }, 
     on_delete => sub { 
      my ($tweet_id, $user_id) = @_; # callback executed when twitter send a delete notification 
     }, 
     timeout => 45, 
); 

$done->recv; 

然而,當我在print_tweet子程序打印出的鳴叫我得到的是:

HASH(0x8f0ad0)HASH(0x8f0640)HASH(0x875990)HASH(0x8f0ab0)HASH(0x8e0d80)HASH(0x8f06e0)HASH(0x8f08f0)HASH(0x93ef30)HASH(0x876190)HASH(0x93ee60)HASH(0x8f0610)HASH(0x8f0b00)HASH(0x8e13e0)HASH(0x93ee20)HASH(0x8f0a20)HASH(0x8e1970)HASH(0x8f0900) 

我甚至想打印出來的鳴叫假設它是一個哈希如下:

sub print_tweet { 
    my ($jsonref, $tweet) = @_; 
    my $tweet = shift; 
    print %tweet; 
} 

然而,那什麼都沒產生。看來,AnyEvent :: Twitter的::流是基於他們的示例代碼返回$鳴叫作爲一個對象:

on_tweet => sub { 
     my $tweet = shift; 
     warn "$tweet->{user}{screen_name}: $tweet->{text}\n"; 
    }, 

而且我知道我可以打印出單獨的對象,但我可以得到德生JSON對象?我必須失去了一些東西還是我的「noob'ness大於我以爲......

UPDATE

I was able to ALMOST get it by changing print_tweet to the following: 

sub print_tweet { 
    my $tweet = shift; 
    my $json_output = to_json($tweet); 
    print $json_output; 
} 

它打印了大部分的JSON對象,但抱怨寬字符,我相信輸出是UTF8格式的問題?我不確定如何解決這個問題,雖然....

回答

1

想通了。需要使用JSON模塊並進行編碼。當你編碼你必須使用{utf8 => 1}選項來說明你從Twitter獲得的utf8字符。最終的代碼在這裏:

#!/Applications/XAMPP/xamppfiles/bin/perl 

use JSON; 
use utf8; 
use AnyEvent::Twitter::Stream; 
    my $done = AnyEvent->condvar; 

BEGIN { 
    use Exporter; 
    our @ISA = qw(Exporter); 
    our @EXPORT = qw{ 
     &init 
    }; 
} 

sub print_tweet { 
    my $tweet = shift; 
    my $json_output = to_json($tweet, {utf8 => 1}); 
    print $json_output; 
    print "\n"; 
} 


    # receive updates from @following_ids 
    my $listener = AnyEvent::Twitter::Stream->new(
     username => XXXXXXXX 
     password => XXXXXXXX 
     method => 'sample', # "firehose" for everything, "sample" for sample timeline 
     on_tweet => sub { 
      my $tweet = shift; 
      print_tweet($tweet); 
     }, 
     on_keepalive => sub { 
      warn "ping\n"; 
     }, 
     on_delete => sub { 
      my ($tweet_id, $user_id) = @_; # callback executed when twitter send a delete notification 
     }, 
     timeout => 45, 
); 

$done->recv; 

感謝你們給的幫助,DataDumper至少讓我驗證格式,它只是沒有產生最終結果。

3

看起來它是返回hashref。如果你不確定,你可以嘗試做這樣的事情。

use Data::Dumper; 

... 

print Dumper $tweet; 

這應該給你的精選傳遞什麼樣的想法,那麼你就可以抓住你想要的 - 可能是這樣的:

print "$tweet->{user}{screen_name}: $tweet->{text}\n"; 
+0

這給出了結構,但它沒有給出原始的JSON對象。 – WildBill

2

print_tweet,你聲明$tweet兩次。首先,將其分配給@_數組的第二個元素,然後重新聲明它併爲其分配第一個元素@_,因爲shift在默認情況下在@_上運行。

當然,如果你已經use warnings打開,你會看到

"my" variable $tweet masks earlier declaration in same scope 

這就是爲什麼你應該總是use strict; use warnings;在你的代碼的頂部。

您看到的輸出字符串是散列引用,打印print_tweet(最初分配給$json_ref)的第一個參數的結果。如果你想打印出$tweet的值,那麼你可以用shift來擺脫你所在的位置。

+0

對不起,我複製了我的代碼的錯誤版本,我已修復它上面。 $ tweet是我發送給print_tweet的第一個參數,它仍然是HASHREF。 – WildBill