2012-02-01 5 views
11

कृपया बताएं कि $_ और @_ का अंतर बिल्कुल सही है। उदाहरण कोड द्वारा दिए गए, का उपयोग कब करें।

+3

क्या पेल्डड परलवार में कुछ ऐसा है जो आपको समझ में नहीं आया? – runrig

+0

हां, आरटीएफएम, मुझे पता है;) –

उत्तर

20

जब एक सबराउटिन में, सरणी @_ दिए गए सबराउटिन को दिए गए तर्क देता है। उदाहरण के लिए:

use strict; 
use warnings; 

sub print_em 
{ 
    foreach my $arg (@_) 
    { 
    print "You passed in $arg.\n"; 
    } 
} 

print_em("foo","bar","baz"); 

उत्पादन

You passed in foo. 
You passed in bar. 
You passed in baz. 

अदिश $_ आम तौर पर एक पाश के भीतर एक चर के रूप में इस्तेमाल किया जाता है। उदाहरण के लिए:

use strict; 
use warnings; 

# Note that we are not declaring a variable 
# that takes on the values 1 through 5. 
foreach(1..5) 
{ 
    print "$_\n"; 
} 

उत्पादन होता है:

1 
2 
3 
4 
5 

इसी तरह, हम थोड़ा ऊपर

रूप
sub print_em 
{ 
    foreach(@_) 
    { 
    print "You passed in $_.\n"; 
    } 
} 

या यहाँ तक कि के रूप में अधिक कॉम्पैक्ट

sub print_em{ print "You passed in $_.\n" foreach(@_);} 
सबरूटीन print_em फिर से लिखा जा सकता था

परिवर्तनीय $_ को कुछ कार्यों के लिए "डिफ़ॉल्ट तर्क" के रूप में भी उपयोग किया जा सकता है। उदाहरण के लिए:

use strict; 
use warnings; 

$_="foobar"; 

if(/bar/) #We do not have to write $_=~/bar/ 
{ 
    print "matched!\n"; 
} 

, जो, matched! आउटपुट करता है।

इन और पर्ल के अन्य "जादू चर" पर अधिक जानकारी के लिए perldoc perlvar पर एक नज़र डालें।

+0

एक perl शुरुआत के रूप में, जो हिस्सा मुझे भ्रमित करता है वह यह है कि '$ _' को डिफ़ॉल्ट इनपुट और पैटर्न खोज स्थान के रूप में वर्णित किया गया है और नीचे सूचीबद्ध फ़ंक्शंस हैं जो डिफ़ॉल्ट रूप से '$ _' का उपयोग करते हैं तर्क: 'पेट, अलार्म, चोप्स, काट, सीआर, क्रोट, कॉस, परिभाषित, eval, exp, glob, हेक्स, int, एलसी, एलसीएफस्ट, लंबाई, लॉग, lstat, mkdir, oct, ord, pos, print , उद्धरण, रीडलिंक, रीडपाइप, रेफ, आवश्यकता, रिवर्स (केवल स्केलर संदर्भ में), आरएमडीआईआर, पाप, विभाजन (इसके दूसरे तर्क पर), वर्ग, स्टेट, स्टडी, uc, ucfirst, अनलिंक, अनपैक। –

+0

आप लिख सकते हैं उदाहरण के लिए 'chomp ($ var)'। या सिर्फ तर्क के बिना 'chomp() '। यदि उत्तरार्द्ध मामला है, तो chomp() $ _ पर ऐसा करेगा। लेकिन सिर्फ एक शुरुआती टिप। मानचित्र, grep या किसी अन्य चीज़ पर सभी "$ _" का उपयोग न करें जहां आपके पास कोई अन्य विकल्प न हो। –

8

जैक मैनी के उत्तर में आपका सटीक प्रश्न शामिल है, लेकिन मैं कुछ भी नोट करना चाहता था: आपको चर के नाम भाग द्वारा बेवकूफ नहीं बनाया जाना चाहिए। सिगल मामलों, साथ ही साथ। $_ और @_$foo और @foo और $bar और %bar जैसी पूरी तरह से भिन्न चर हैं। पर्ल उन्हें एक-दूसरे से पूरी तरह अलग करता है।

+0

+1: एक बहुत अच्छा बिंदु। [Typeglobs] (http://perldoc.perl.org/perldata.html#Typeglobs-and-Filehandles) की स्पष्ट घोषणा से बचने के लिए यह भी एक अच्छा कारण है, क्योंकि अधिकतर अब आपको उनकी आवश्यकता नहीं है। 'Foreach (@a) { प्रिंट पढ़ने के बाद –

3

एक आम तौर पर देखा उदाहरण उदाहरण I/O के साथ करना था। यह कोड ...

while(<>) 
{ 
    chomp; 
    print if(m/^chr1/); 
} 

... इस कोड के कार्यात्मक रूप से बराबर है।

while(my $line = <STDIN>) 
{ 
    chomp($line); 
    print($line) if($line =~ m/^chr1/); 
} 

किसी भी समय आप एक पाश $_ चर से भर जाता है है, लेकिन वहाँ भी एक और अधिक स्पष्ट वाक्य रचना है। यह कोड ...

foreach(@a) 
{ 
    print; 
    chomp; 
    push(@b, $_) 
} 

... इस कोड के कार्यात्मक रूप से बराबर है। $_ और अन्य जादू चर के साथ ध्यान में रखने की

foreach my $value(@a) 
{ 
    print($value); 
    chomp($value); 
    push(@b, $value); 
} 

एक बात यह है कि वे एक उपन्यास प्रोग्रामर के लिए काफी गुप्त हो सकता है। समय के साथ, मैंने अधिक स्पष्ट वाक्यविन्यास के पक्ष में इन कम और कम उपयोग किए हैं (उम्मीद है कि) दूसरों के लिए कोड के इरादे को समझना आसान बनाता है।

+1

; चॉम्प; पुश (@ बी, $ _) } 'पहली बात मैंने सोचा था: "मैं नफरत करता हूं" तो मैंने आगे पढ़ा' मेरा $ मूल्य (@ ए) { प्रिंट ($ मूल्य); चॉम्प ($ मूल्य); पुश (@ बी, $ मूल्य); } 'वही करता है, तब से मैंने सोचा: "मुझे प्यार है!" :-) –

1

न तो $_ और न ही @_ स्वाभाविक रूप से विशेष है। वैश्विक होने के अलावा, वे पूरी तरह से सामान्य चर हैं। वे जादुई नहीं हैं। कुछ भी विशेष नहीं होता है जब कोई उन्हें सौंपता है या उनसे पढ़ता है।

कारण @_ का उपयोग अक्सर पर्ल फ़ंक्शन के तर्कों को स्थानांतरित करता है। यदि आप अपने उप-पास में दिए गए तर्क प्राप्त करना चाहते हैं, तो आपको @_ तक पहुंचने की आवश्यकता होगी।

sub f { 
    my ($x, $y) = @_; 
    ... 
} 

कारण $_ इतनी बार प्रयोग किया जाता है कि कुछ पर्ल ऑपरेटरों डिफ़ॉल्ट रूप से इसे करने के लिए आवंटित है, और दूसरों को उनके तर्क के लिए एक डिफ़ॉल्ट के रूप में अपने मूल्य का उपयोग करें। यदि आप इसे गले लगाते हैं तो इससे छोटे कोड हो सकते हैं, लेकिन इसका उपयोग करने के लिए में नहीं है।

for my $x (@x) { say $x; } 
    vs 
for (@x) { say; } 
+1

त्रुटि, कुछ विशेष रूप से तब होता है जब आप sub_outine में @_ को असाइन करते हैं, उदाहरण के लिए: sub addX {$ _ [0]। = 'X'} my $ foo = 'foo'; addX ($ foo); प्रिंट $ foo; # :-) – tadmc

+0

@tadmc, मुझे काफी पता है कि उप कॉल नए बनाने के बजाय '@ _' के तत्वों के लिए मौजूदा स्केलर का उपयोग करती है। इसे एलियासिंग कहा जाता है, और यह किसी भी चर के साथ किया जा सकता है, न कि केवल '@ _' के तत्वों के साथ। जैसे '$ Y = 4; $ x ($ y) के लिए {$ x = 5; } $ y कहें; '। एक चर के लिए दो नाम होने से परिवर्तनीय विशेष नहीं होता है। यह वास्तव में बहुत आम है। (कभी एक सब आयात करें?) – ikegami

+0

@ikegami => इस तथ्य को छोड़कर कि सामान्य उपयोग (उन्हें PERL असाइन करना) दोनों में '@ _' और' $ _' में आमतौर पर उपनाम होते हैं, जो निश्चित रूप से एक "विशेष" व्यवहार होता है। तो हाँ, जब आप उन्हें असाइन करते हैं तो आमतौर पर कुछ विशेष होता है। –

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