2010-02-25 15 views
6

निम्न स्निपेट बिल्कुल क्यों काम करता है? और इसका उपयोग करके क्या बुरा हो सकता है? लेकिन गंभीरता से, क्या कोई कारण है, ${} में कोड का मूल्यांकन किया जाता है और फिर स्केलर संदर्भ के रूप में उपयोग किया जाता है?

use strict; 
no strict 'refs'; 

our $message = "Hello world!"; 
print "${ lc 'MESSAGE' }\n";
+4

आपने स्पष्ट रूप से कहा है कि आप प्रतीकात्मक संदर्भों का उपयोग करना चाहते हैं और 'perl' ने आपकी बोली-प्रक्रिया की है। –

+0

इस तरह dereferencing काम करता है। आपको सहायक मिल सकता है: http://perlmonks.org/?node=References+quick+reference – ysth

उत्तर

2

यह ठीक है, unless you use symbolic references। निम्नलिखित कोड मान लीजिए:

my %messages = (hello => "Hello world!", bye => "Bye-bye, world!"); 
sub get_message_ref { return \$messages{$_[0]} }; # returns scalarref 
print "${ get_message_ref('bye') }\n"; 

सहमत, इसकी उपयोगिता scalarrefs साथ स्पष्ट नहीं है, लेकिन यह arrayrefs साथ बहुत उपयोगी है।

print "keys: @{[keys %messages]}\n"; 
+0

http://stackoverflow.com/tags/perl+symbolic-reference –

+0

मुझे '$ की सेटिंग के आधार पर पसंद नहीं है "', इसलिए मैं केवल एक स्केलर लौटने वाली अभिव्यक्ति के लिए इसका उपयोग करूंगा। और इसके लिए, '" $ {\ expr} "' '{{expr]}" ', जैसा कि कम सममित है, उतना ही अच्छा है। – ysth

+0

@ysth ठीक है, आपने मुझे पकड़ा है। मैं आपसे सहमत हूं।लेकिन जब आप सिर्फ एक बार की स्क्रिप्ट लिख रहे हैं, तो यह बिल्कुल ठीक है। – codeholic

4
से

"Using References" section of the perlref documentation:

कहीं भी आप एक चर या सबरूटीन नाम के हिस्से के रूप में पहचान करने के लिए (या पहचानकर्ता की श्रृंखला) डाल हैं, तो आप पहचानकर्ता एक ब्लॉक के साथ एक संदर्भ लौटने की जगह ले सकता सही प्रकार का। दूसरे शब्दों में, पिछले उदाहरण इस तरह लिखा जा सकता है:

$bar = ${$scalarref}; 
push(@{$arrayref}, $filename); 
${$arrayref}[0] = "January"; 
${$hashref}{"KEY"} = "VALUE"; 
&{$coderef}(1,2,3); 
$globref->print("output\n"); # iff IO::Handle is loaded 

बेशक, यह इस मामले में curlies उपयोग करने के लिए एक छोटे से मूर्ख है, लेकिन ब्लॉक किसी भी मनमाने ढंग से अभिव्यक्ति हो सकते हैं, विशेष रूप से, subscripted भाव:

&{ $dispatch{$index} }(1,2,3); # call correct routine 
क्योंकि $$x के सरल मामले के लिए curlies छोड़ करने में सक्षम होने की

, लोगों को अक्सर उचित ऑपरेटर के रूप में अपसंदर्भन प्रतीकों को देखने की गलती है, और उनके पूर्वता के बारे में चिंता। यदि वे थे, तो आप ब्रेसिज़ के बजाय ब्रांड्स का उपयोग कर सकते थे। ऐसा नहीं है। नीचे दिए गए अंतर पर विचार करें; मामले 0 मामले 1 की एक छोटी-हाथ संस्करण है, 2 मामला नहीं:

$$hashref{"KEY"} = "VALUE";  # CASE 0 
${$hashref}{"KEY"} = "VALUE";  # CASE 1 
${$hashref{"KEY"}} = "VALUE";  # CASE 2 
${$hashref->{"KEY"}} = "VALUE"; # CASE 3 

केस 2 भी है कि में भ्रामक आप एक चर %hashref बुलाया तक पहुँच रहे हैं, हैश यह शायद संदर्भित है करने के लिए $hashref के माध्यम से नहीं अपसंदर्भन है। उस मामले 3.

बाद में होगा "प्रतीकात्मक संदर्भ" में:

हम ने कहा कि संदर्भ अस्तित्व में वसंत के रूप में आवश्यक अगर वे अपरिभाषित हैं, लेकिन हम यह नहीं कहा कि क्या एक मूल्य अगर ऐसा होता एक संदर्भ के रूप में इस्तेमाल किया गया है पहले से ही परिभाषित किया गया है, लेकिन एक कठिन संदर्भ नहीं है। यदि आप इसे संदर्भ के रूप में उपयोग करते हैं, तो इसे प्रतीकात्मक संदर्भ के रूप में माना जाएगा। यही है, स्केलर का मूल्य किसी (संभवतः) अज्ञात मान के प्रत्यक्ष लिंक के बजाय एक चर का नाम माना जाता है।

+0

रेफरी के बारे में व्यापक स्पष्टीकरण के लिए धन्यवाद, लेकिन सवाल यह था कि * {...} की सामग्री को डबल-उद्धृत स्ट्रिंग में क्यों मूल्यांकन किया जाता है और यदि इस व्यवहार में कोई उपयोगी अनुप्रयोग है। :) – willert

+1

@ विल्लर्ट हां, और मैंने दस्तावेज में विशिष्ट अनुच्छेदों का हवाला दिया जो बता रहा है कि क्या हो रहा है: पहले उद्धृत वाक्य (जोर जोड़ा गया) की शुरुआत पर ध्यान दें: "कहीं भी आप पहचानकर्ता रखेंगे ... आप पहचानकर्ता को ब्लॉक के साथ बदल सकते हैं ... "एक पर्ल ब्लॉक घुंघराले ब्रेसिज़ से घिरा मनमाना कोड है। –

12

हम Intermediate Perl में गहराई से इसकी व्याख्या करते हैं।

चर लुकअप के लिए सामान्य वाक्य रचना है:

SIGIL BLOCK INDEXY-THING 

एक सरल अदिश कि लगता है कि के लिए:

print $ { foo }; 

आप शायद इस देखा है जब आप आसपास के चीजों से एक चर नाम को अलग करने की जरूरत है यह:

print "abc${foo}def\n"; 

यदि आपके पास ब्लॉक में एक पर्ल पहचानकर्ता है और कोई आसपास गंदगी, आप ब्रेसिज़ बंद छोड़ सकते हैं, जो आम मामला है:

print $foo; 

बहरहाल, यह एक संदर्भ अपसंदर्भन के लिए एक ही बात है:

SIGIL BLOCK-RETURNING-REFERENCE INDEXY-THINGS 

तो बात यह है कि आप में मिलता है ब्लॉक, एक संदर्भ है पर्ल यह भिन्नता की कोशिश करता है की तरह आप भी इसे पूछा:

my $ref = \ '12345'; 
print $  { $ref }; 

हालांकि कोई वास्तविक ब्लॉक है यही कारण है, और न सिर्फ चीनी। जैसा कि आप में जितने चाहें उतने बयान हो सकता है:

print $  { my $ref = \ '1234'; $ref }; 

अब आप सिर्फ एक पर्ल पहचानकर्ता निर्दिष्ट नहीं कर रहे हैं, इसलिए पर्ल स्वीकार नही करता है कि आप इसे एक पहचानकर्ता दे रहे हैं और यह कोड का उपयोग करता कार्यान्वित एक संदर्भ के रूप में परिणाम। इन लगभग समान say बयानों के बीच अंतर पर विचार करें:

use 5.010; 
our $foo = "I'm the scalar"; 

sub foo { \ "I'm the sub" } 

say ${foo}; 
say ${foo;}; 

कि दूसरी say पर्ल में सेमी-कोलन को देखता है, यह जानता है यह एक पहचानकर्ता नहीं है, पाठ के रूप में ब्रेसिज़ के अंदर कोड की व्याख्या, और परिणाम देता है। चूंकि परिणाम एक संदर्भ है, इसलिए यह ${...} का उपयोग इसे अस्वीकार करने के लिए करता है। इससे कोई फर्क नहीं पड़ता कि आप यह कहां करते हैं, ताकि आप इसे डबल-उद्धृत स्ट्रिंग के अंदर कर सकें, विशेष नहीं है।

इसके अलावा, our पर ध्यान दें। यही कारण है कि अब महत्वपूर्ण है कि आप कुछ में थोड़ा और अधिक मुश्किल विचार करने के लिए जा रहे हैं:

use 5.010; 
our $foo = "I'm the scalar"; 

sub foo { \ "I'm the sub" } 
sub baz { 'foo' } 

say ${foo}; 
say ${foo;}; 
say ${baz;}; 

पर्ल है कि पिछले say कोड के रूप में intreprets है और देखता है परिणाम एक संदर्भ नहीं है, यह सरल स्ट्रिंग foo है। पर्ल देखता है कि यह संदर्भ नहीं है लेकिन अब यह एक संदर्भ संदर्भ में है, इसलिए यह एक प्रतीकात्मक संदर्भ (Greg Bacon describes) के रूप में करता है। चूंकि प्रतीकात्मक संदर्भ प्रतीक तालिका में चर के साथ काम करते हैं, इसलिए $foo को एक पैकेज चर होना था।

चूंकि इसे गड़बड़ करना आसान है, strict इसके लिए एक आसान जांच है। हालांकि, जब आप इसे बंद करते हैं, तो यह आपको काटते समय आश्चर्यचकित न हों। :)

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