2013-10-18 9 views
7

पर कृपया नीचे दिए गए कोड को देखने के मामले में अपसंदर्भन:

$scalar = 10; 

subroutine(\$scalar); 

sub subroutine { 
    my $subroutine_scalar = ${$_[0]}; #note you need the {} brackets, or this doesn't work! 
    print "$subroutine_scalar\n"; 
} 

कोड में ऊपर आप टिप्पणी लिखा देख सकते हैं "नोट आपको {} ब्रैकेट की आवश्यकता है, या यह काम नहीं करता है! " ।

my $subroutine_scalar = $$_[0]; 

अर्थात कर्ली कोष्ठक का उपयोग किए बिना: कारण यह है कि हम क्यों नहीं कर सकते एक ही बयान के रूप में उपयोग की व्याख्या करें।

उत्तर

2

${ $x }[0]$x द्वारा संदर्भित सरणी में तत्व 0 के मान को पकड़ता है।

${ $x[0] } सरणी @x के तत्व 0 द्वारा संदर्भित स्केलर के मान को पकड़ता है।

>perl -E"$x=['def']; @x=\'abc'; say ${ $x }[0];" 
def 

>perl -E"$x=['def']; @x=\'abc'; say ${ $x[0] };" 
abc 

$$x[0]${ $x }[0] के लिए कम है।

>perl -E"$x=['def']; @x=\'abc'; say $$x[0];" 
def 
1

क्योंकि $$_[0] मतलब है ${$_}[0]

sub subroutine1 { 
    my $scalar = 10; 
    my $ref_scalar = \$scalar; 
    my @array = ($ref_scalar); 
    my $subroutine_scalar = ${$array[0]}; 

    print "$subroutine_scalar\n"; 
} 

sub subroutine2 { 
    my @array = (10); 
    my $ref_array = \@array; 
    my $subroutine_scalar = $$ref_array[0]; 

    print "$subroutine_scalar\n"; 
} 

subroutine1 में, @array$scalar के संदर्भ युक्त एक सरणी है:

कोड है जो दोनों प्रिंट 10 के इन दो टुकड़े पर विचार करें। तो पहला चरण $array[0] द्वारा पहला तत्व प्राप्त करना है, और फिर इसे सम्मानित करना है।

subroutine2 में, @array एक सरणी 10 युक्त एक सरणी है, और $ ref_array इसका संदर्भ है। तो पहला चरण $ref_array द्वारा सरणी प्राप्त करना है, और उसके बाद सरणी अनुक्रमणिका।

2
my $subroutine_scalar = $$_[0]; 

@_ सरणी के पहले तत्व के लिए एक ही रूप में

my $subroutine_scalar = $_->[0]; # $_ is array reference 

दूसरी ओर,

my $subroutine_scalar = ${$_[0]}; 

dereferences अदिश रेफरी है, और

my ($sref) = @_; 
my $subroutine_scalar = ${$sref}; # or $$sref for short 
8
के रूप में लिखा जा सकता है

कई लोगों के पास अल है यहां दिए गए सही उत्तर तैयार हैं। मैं एक उदाहरण जोड़ना चाहता था जो मुझे रोशनी मिली। अधिक जानकारी के लिए आप perldoc perlref में प्रलेखन पढ़ सकते हैं।

आपकी समस्या अस्पष्टता में से एक है, तो आप दो आपरेशन $$ और [0] एक ही पहचानकर्ता _ पर काम कर रहा है, और परिणाम पर निर्भर करता है आपरेशन पहले किया जाता है। हम समर्थन घुंघराले ब्रेसिज़ ${ ... } का उपयोग कर इसे कम अस्पष्ट बना सकते हैं। $$_[0] (एक इंसान वैसे भी के लिए) संभवतः अर्थ हो सकता है:

  • ${$$_}[0] - अदिश $_ भिन्नता है, तो इसके पहले तत्व ले लो।
  • ${$_[0]} - सरणी सरणी @_ के तत्व ले लो और इसे कम करें।

जैसा कि आप देख सकते हैं, इन दो मामलों में पूरी तरह से भिन्न चर, @_ और $_ का संदर्भ मिलता है।

बेशक, पर्ल के लिए यह संदिग्ध नहीं है, हमें बस पहला विकल्प मिलता है, क्योंकि मुख्य लुकअप से पहले डीरफ्रेंसिंग किया जाता है। हमें इस ड्रेफ्रेंसिंग को ओवरराइड करने के लिए समर्थन घुंघराले ब्रेसिज़ की आवश्यकता है, और यही कारण है कि आपका उदाहरण समर्थन ब्रेसिज़ के बिना "काम" नहीं करता है।

आप अपने सबराउटिन के लिए थोड़ा कम भ्रमित कार्यक्षमता पर विचार कर सकते हैं। एक बार में दो बातें करते हैं की कोशिश कर के बजाय (तर्क और यह भिन्नता मिल), तो आपको दो चरणों में यह कर सकते हैं:

sub foo { 
    my $n = shift; 
    print $$n; 
} 

यहाँ, हम shift साथ @_ बंद पहला तर्क ले, और फिर इसे भिन्नता। स्वच्छ और सरल।

अक्सर, आप स्केलर चर के संदर्भों का उपयोग नहीं करेंगे, हालांकि। और उन मामलों में, आप तीर ऑपरेटर ->

my @array = (1,2,3); 
foo(\@array); 

sub foo { 
    my $aref = shift; 
    print $aref->[0]; 
} 

मैं तीर ऑपरेटर का उपयोग मिल $$ वाक्य रचना के लिए बेहतर होगा करने के लिए का उपयोग कर सकते हैं।

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