2011-03-01 9 views
11

क्या यह बताने का कोई तरीका है कि हैश संदर्भ प्रतीक तालिका का जिक्र कर रहा है या नहीं?आप नियमित हैश चर से प्रतीक तालिका को कैसे अलग करते हैं?

है, कैसे समारोह

sub foo { 
    my ($hashref) = @_; 
    ... 
} 

जान सकता है कि क्या यह नहीं बल्कि

foo(\%main) 

से

foo(\%main::) 

के रूप में लागू किया गया था?

एप्लिकेशन एक ऐसा फ़ंक्शन है जो कभी-कभी tie हैश वैरिएबल है, लेकिन मैं प्रतीक तालिका को बांधने से बचाना चाहता हूं।

उत्तर

7

ऐसा लगता है कि यह HvNAME का उपयोग कर सी एपीआई से किया जा सकता है।

एक गुप्त कोष, या शून्य के पैकेज के नाम वापस लौटाता गुप्त कोष में एक गुप्त कोष में नहीं है

HvNAME: निम्नलिखित perlapi से है। SvSTASH, CvSTASH देखें।

  1. चार * HvNAME (एचवी * गुप्त कोष)
+2

मैं इसे 'perl -MDevel :: Peek -e' डंप (\% a: :), डंप (\% ए) ''चलाने से इसे कम करने के लिए शुरू कर रहा था। लिंक के लिए धन्यवाद ताकि मैं कम माल-संवर्धन कर सकूं। एक्सएस के बिना आप अभी भी '$ is_a_symtable = do {$ sv = B :: svref_2object ($ हैशफ) जैसे कुछ कर सकते हैं; रेफरी ($ sv) eq 'B :: HV' && $ sv-> NAME};' – mob

3

आप '::' में समाप्त होने वाली कुंजियों को देख सकते हैं, जो इंगित करेंगे कि इसमें अन्य पैकेज हैं, या सभी मान प्रतीक रेफरी हैं।

  • बेशक, यहां तक ​​कि यहां एक हैश से छेड़छाड़ करना मुश्किल होगा जो प्रतीकों को संग्रहीत करता है (किसी भी कारण से)। मैं B::svref_2object के साथ चारों ओर घूम रहा था, लेकिन नियमित हैश में संग्रहीत स्टैश से प्रतीकों को भी $sym->can('STASH') के लिए कुछ वापस कर दिया जाएगा।

मुझे लगता है कि आप जो चीज कर सकते हैं वह प्रतीक तालिका के माध्यम से उतरती है और देखें कि एक ही स्मृति स्थान पर एक स्टैश पॉइंट्स हैं या नहीं।

इस तरह का प्रकार:

use Scalar::Util qw<refaddr>; 
my %seen; 

sub _descend_symtable { 
    $calls++; 
    my ($cand, $stash_name) = @_; 
    my $stash = do { no strict 'refs'; \%{ $stash_name }; }; 
    return if $seen{ refaddr($stash) }++; 
    return $stash_name if $cand == $stash; 

    my $result; 
    foreach my $s (grep { m/::$/ } keys %$stash) { 
     $result = _descend_symtable($cand, "$stash_name$s") 
      and return $result; 
    } 
    return; 
} 

sub find_in_symtable { 
    my $needle = shift; 
    %seen  =(); 
    return _descend_symtable($needle, 'main::'); 
} 

प्रदर्शन भयानक नहीं था।

+0

यह एक अच्छी शुरुआत है और मुझे वहाँ रास्ते से 95% मिलेगा, मुझे लगता है। यह परीक्षण खाली पैकेज ('foo (\% खाली :: पैकेज)' बनाम 'foo ({}) ') के लिए संदिग्ध होगा और झूठी सकारात्मक' foo ({'abc ::' => * मुख्य के लिए धोखा दिया जा सकता है :: abc ::}) 'या झूठी नकारात्मक (' $ blankpkg :: {"def"} = "xyz"; foo (\% emptypkg: :) ')। कुछ और मूर्खतापूर्ण? – mob

संबंधित मुद्दे