2011-12-26 89 views
0

我試圖在Perl 5.8.8中傳遞哈希引用,我知道這應該是一件很平凡的事情。我通過散列遍佈在我的代碼的地方,但由於某種原因,它不會在這個子程序工作:在Perl中傳遞哈希引用

sub build_results_hash { 
    my %results; 
    my $search = $_[0]; 
    my $json = $_[1]; 
    my $json_passed = $_[2]; 

    my $dbh = db_connect(-db=>'ghgs'); 

    my $db_search = html_db_input($search,$dbh); 
    %results = db_hoh(-query=>"SELECT listing_id,MATCH(search) AGAINST($db_search) as relevance FROM search WHERE MATCH(search) AGAINST($db_search) LIMIT 1000",-key=>"listing_id",-dbh=>$dbh); 

    if(($json_passed == 1) and ($json ne '[]')) 
    { 
     narrow_results_hash(\%results,$search,$dbh,$json); 
    } 

    db_x($dbh); 

    return \%results; 
} 

sub db_hoh { 
    # ... 
    return %hoh; 
} 

db_hoh剛剛返回哈希散列。問題是我打電話narrow_results_hash並通過%results;這是行不通的。但是,如果我刪除圍繞該方法調用的if語句,那麼散列傳遞正常!我不確定什麼會導致這種行爲。這裏是我收到的哈希:

sub narrow_results_hash 
{ 
    use JSON::XS; 
    my $params = shift; 
    my %results = %$params; 
    # ... 
    print join(',',keys %results), "\n"; 
    # ... 
} 

如果我刪除周圍narrow_results_hash呼叫if聲明build_results_hash,它打印:「107,99,34」。但是,如果if語句存在於該調用周圍,則會打印出「HASH(0x7fd61fbf0580)」。

+1

什麼,確切地說,[你的意思](http://catb.org/~esr/faqs/smart-questions.html#beprecise)「不起作用」?另外,請將示例代碼縮減爲[最小測試用例](http://sscce.org/)。事實上,它不是獨立的。 – outis

+2

Re:「我在我的代碼中遍佈散列」,不能將散列傳遞給subs(只是一個標量列表),subs不能返回散列(只是一個標量列表)。 – ikegami

+0

使用[Data :: Dumper](http://search.cpan.org/~smueller/Data-Dumper-2.131/Dumper.pm)查看'%results'並確保它是散列哈希,因爲您相信。我嘗試查找db_hoh方法,但在DBI文檔中找不到它。我懷疑'db_hoh'可能會返回一個***引用***到哈希散列。 –

回答

1

db_hoh可能會返回散列引用而不是散列。嘗試使用標量作爲結果變量。

my %results; 

成爲

my $results; 

等等...

2

我有一個評論過多評論。

對於您的實際問題,我們需要了解一些能夠幫助您的事情。

  1. 什麼是db_hoh返回,對散列的引用或者鍵值對的列表。
  2. 你是什麼意思,「不起作用」?它根本沒有工作嗎?它完成了一些操作,但給你一個意想不到的結果?

此外,我對你的代碼有一些文體上的評論。從我看來,你來自C世界,對嗎?

  1. 開箱@_爲列表分配清潔尋找
  2. 聲明%results可以等待,直到它被填充
  3. 除非我誤解,你不需要使用$json_passed,而是你可以測試是否$json定義
  4. narrow子,你能避免創建$params

他再次是更新後的代碼:

sub build_results_hash { 
    my ($search, $json) = @_; 

    my $dbh = db_connect(-db=>'ghgs'); 

    my $db_search = html_db_input($search,$dbh); 
    my %results = db_hoh(
     -query=>"SELECT listing_id,MATCH(search) AGAINST($db_search) as relevance FROM search WHERE MATCH(search) AGAINST($db_search) LIMIT 1000", 
     -key=>"listing_id", 
     -dbh=>$dbh 
    ); 

    if((defined $json) and ($json ne '[]')) 
    { 
     narrow_results_hash(\%results,$search,$dbh,$json); 
    } 

    db_x($dbh); 

    return \%results; 
} 

sub narrow_results_hash 
{ 
    use JSON::XS; #unless you expect this import to be local it looks funny here 
    my %results = %{ shift() }; 
    # ... 
} 

最後,可能也是最重要的,除非html_db_input正在清理存儲在$db_search輸入,你離開自己開放給SQL injection攻擊。它看起來好像你有你自己的DB訪問庫,但如果你使用DBI我會做這樣的事情:

my $dbh = ...; # connect to db 
my $sth = $dbh->prepare('SELECT listing_id,MATCH(search) AGAINST(?) as relevance FROM search WHERE MATCH(search) AGAINST(?) LIMIT 1000'); 
$sth->execute($db_search,$db_search); 
my $results = $sth->fetchall_hashref('listing_id'); 

這可以防止$db_search內容來改變你的SQL語句。

+0

要回答您的初始問題,1. db_hoh()方法結尾處的返回行是「return%hoh;」 2.在我的narrow_results_hash方法中,我在我的%結果哈希上使用連接,例如「join(',',keys%results);」如果我打印這個,並且我移除了在narrow_results_hash調用周圍的if語句,我得到這樣一個列表:「107,99,34」。但是,如果if語句存在於調用周圍,那麼我得到:HASH(0x7fd61fbf0580)。 – srchulo

+0

您使用的Perl版本是?從版本[5.14](http://p3rl.org/perl5140delta),許多函數(如['keys'](http://p3rl.org/keys))可以引用以及散列(或數組)和它們將自動解除引用。由於你直接打印的結果是HASH(0xnnnnnnn),你肯定有一個hashref而不是一個散列。它看起來好像需要進一步的解引用。 –

+0

我正在使用版本5.8.8。 – srchulo