2011-02-01 18 views
16

Demystifying this question में पोस्टर कैसे एक पंक्ति में निम्न कार्य करने के लिए कहापर्ल ग्लोब (*)

sub my_sub { 
    my $ref_array = shift; 
    for (@$ref_array) { 
     #do somthing with $_ here 
    }; 

    #use $ref_array->[$element] here 
} 

हालांकि this answer में एसओ के स्थानीय भिक्षुओं में से एक सुझाव दिया tchrist:

sub my_sub { 
    local *array = shift(); 
    #use @array here 
} 

जब मैं

पूछा मध्य स्तर पर्ल जादू जानने की कोशिश कर में, मैं पूछ सकते हैं, यह क्या है कि आप यहाँ क्या करने के लिए स्थापित कर रहे हैं? क्या आप एररफ में @array का संदर्भ सेट कर रहे हैं? कैसे क्या आप जानते हैं कि आप @array और % array या $ array नहीं बनाते हैं? मैं कहां से * ऑपरेटर (perlop?) के बारे में और जान सकता हूं। धन्यवाद!

मुझे इसे एक नई पोस्ट के रूप में पूछने का सुझाव दिया गया था, हालांकि उन्होंने अच्छे संदर्भ दिए थे। वैसे भी, यहाँ जाता है? क्या कोई कृपया बता सकता है कि% सरणी या $ सरणी के बजाय @array कैसे बनता है और कैसे बनाया जाता है? धन्यवाद।

+0

आप शायद [इस उत्तर] से टाइपग्लब्स में कई महत्वपूर्ण अंतर्दृष्टि प्राप्त कर सकते हैं (http://stackoverflow.com/questions/3807231/how-can-i-test-if-i-can-write-to-a- filehandle/4200474 # 4200474), जिनमें से कोई भी यहां तक ​​छुआ नहीं गया है। – tchrist

उत्तर

21

असाइनमेंट कुछ जादू है कि VALUE (जैसे कि, की, कहते हैं, Scalar::Util::reftype(VALUE) वापसी मान) के प्रकार पर निर्भर होता है। यदि VALUE स्केलर, सरणी, हैश, या सबराउटिन का संदर्भ है, तो केवल प्रतीक तालिका में प्रविष्टि ओवरराइट की जाएगी।

यह मुहावरा

local *array = shift(); 
#use @array here 

काम करता दस्तावेज के रूप में जब सबरूटीन के लिए पहला तर्क एक सरणी संदर्भ है। यदि पहला तर्क इसके बजाय, एक स्केलर संदर्भ कहता है, तो केवल $array और @array असाइनमेंट से प्रभावित नहीं होगा। perlmod और perldata पर

 
@array = new array 
$array = original scalar 
%array = originalhash 
------------------ 
@array = orignal array 
$array = new scalar 
%array = originalhash 
------------------ 
@array = orignal array 
$array = original scalar 
%array = newhash 
------------------ 
@array = foo bar 
$array = foo 
%array = FOOfoo 
------------------ 
@array = foo bar 
$array = foo 
%array = FOOfoo 
------------------ 
@array = 
$array = 
%array = 
------------------ 
@array = orignal array 
$array = original scalar 
%array = originalhash 
------------------ 

अतिरिक्त दस्तावेज़:

एक छोटी सी डेमो स्क्रिप्ट देखने के लिए क्या हो रहा है:

no strict; 

sub F { 
    local *array = shift; 

    print "\@array = @array\n"; 
    print "\$array = $array\n"; 
    print "\%array = ",%array,"\n"; 
    print "------------------\n"; 
} 

$array = "original scalar"; 
%array = ("original" => "hash"); 
@array = ("orignal","array"); 

$foo = "foo"; 
@foo = ("foo","bar"); 
%foo = ("FOO" => "foo"); 

F ["new","array"];  # array reference 
F \"new scalar";   # scalar reference 
F {"new" => "hash"};  # hash reference 
F *foo;     # typeglob 
F 'foo';     # not a reference, but name of assigned variable 
F 'something else';  # not a reference 
F();      # undef 

आउटपुट।संदर्भ से पहले दिन में पर्ल का एक हिस्सा था, यह मुहावरे सर्राउटिन में सरणी और हैश पास करने के लिए सहायक था।

+1

अब आप क्यों शासन नहीं करते? – hobbs

+0

भूलें कि क्या होता है जब एक टाइपग्लोब असाइनमेंट में आरएचएस न तो एक टाइपग्लोब होता है और न ही एक संदर्भ लेकिन स्ट्रिंग होता है। यह भी विचार करें कि क्या होता है जब '*' सिगिल का ऑपरेंड एक स्ट्रिंग नहीं होता है। अंत में, 'स्थानीय' पर विचार करें। – tchrist

+0

जैसा कि यह उत्तर दिखाता है, एक ग्लोब को असाइनमेंट संदर्भ प्रकार के आधार पर विभिन्न स्लॉट भरता है। आप यह सुनिश्चित कर सकते हैं कि आपके पास उचित प्रकार है: 'local * array = \ @ {shift @_}'। यदि संदर्भ एक सरणी है, तो संदर्भ/dereference जोड़ी \ @ 'पारदर्शी है, लेकिन अन्यथा एक त्रुटि फेंक देगा। –

3

पर्ल के मेरे स्वीकार्य रूप से कम से कम जादूगर ज्ञान के साथ, मैं एक उत्तर प्राप्त करूंगा। * ऑपरेटर प्रतीक तालिका प्रविष्टि असाइन करता है। जैसा कि मैं इसे समझता हूं, @array,% array, और $ array सभी स्ट्रिंग 'सरणी' के लिए समान प्रतीक तालिका प्रविष्टि को संदर्भित करते हैं, लेकिन उस प्रविष्टि के विभिन्न फ़ील्ड में: ARRAY, HASH, और SCALAR फ़ील्ड। तो local *array = shift; असाइन करने से वास्तव में कॉलर में उपयोग किए जाने वाले कार्यों के लिए 'सरणी' (ARRAY, HASH, और SCALAR फ़ील्ड समेत) के लिए संपूर्ण स्थानीय प्रतीक तालिका प्रविष्टि असाइन की जाती है। एक ग्लोब

*glob = VALUE 

को

+1

यदि असाइन की गई चीज़ एक ग्लोब या ग्लोबफ है, हाँ; अन्यथा यह अधिक जटिल है। दरअसल, यह और भी जटिल है, क्योंकि एक प्रतीक तालिका प्रविष्टि एक "ग्लोब वैरिएबल" की तरह है जो "ग्लोब वैल्यू" रखती है, और असाइनमेंट वैल्यू पार्ट सेट करता है, वैरिएबल ही नहीं। – ysth

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