2012-02-06 14 views
7

पर्ल में एकल चर को encapsulate, क्या डबल कोट्स (कोई concatenation) में एक एकल चर encapsulate करने का कोई कारण है?perl डबल कोट्स

मैं अक्सर कार्यक्रम मैं पर काम कर रहा हूँ के स्रोत (लोगों की है कि यहां काम नहीं करते द्वारा 10 साल पहले लिखा अब) में यह लगता है: जहाँ तक मैं वहाँ पता है

my $sql_host = "something"; 
my $sql_user = "somethingelse"; 

# a few lines down 
my $db = sub_for_sql_conection("$sql_host", "$sql_user", "$sql_pass", "$sql_db"); 

कोई कारण नहीं है यह करने के लिए। जब मैं एक पुरानी लिपि में काम करता हूं तो मैं सामान्य रूप से उद्धरण हटा देता हूं, इसलिए मेरा संपादक उन्हें तारों के रूप में चर के रूप में रंग देता है।

मुझे लगता है कि उन्होंने इसे कहीं देखा और बिना समझ के शैली को कॉपी किया क्यों ऐसा है। क्या मैं कुछ भूल रहा हूँ ?

धन्यवाद।

+2

क्योंकि जवाब यहां दिखाने के यह एक अच्छा सवाल है बस कैसे सावधान आप जब फिर से बाँटे पुराने कोड होना चाहिए - वहां कुछ ऐसा करने का एक अच्छा कारण हो सकता है जो पहली बार खराब शैली की तरह दिखाई देता है। – tangent

उत्तर

7

यह सब स्पष्ट रूप से चर को मजबूत करता है। 99.9% मामलों में, यह किसी प्रकार की नौसिखिया त्रुटि है।

my $foo = "1234"; 
sub bar { $_[0] =~ s/2/two/ } 
print "Foo is $foo\n"; 
bar("$foo"); 
print "Foo is $foo\n"; 
bar($foo); 
print "Foo is $foo\n"; 

यहाँ, stringification एक कॉपी बन जाएगी और पारित कर दिया है कि सबरूटीन के लिए, संदर्भ अर्थ विज्ञान द्वारा पर्ल के पास circumventing:

वहाँ चीजें हैं जो इस बुला शैली का एक पक्ष प्रभाव के रूप में हो सकता है कर रहे हैं। इसे आम तौर पर बुलाए जाने वाले चरों को बुझाने के लिए बुरी आदत माना जाता है, इसलिए आप शायद ठीक हैं।

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

एक गहरी डरावनी चीज़ भी है जो चल रही है। यदि आप एक्सएस कोड के साथ काम कर रहे हैं जो किसी फ़ंक्शन में स्केलर तर्कों पर सेट किए गए झंडे को देखता है, तो स्केलर को स्ट्रिंग करना एक आसान तरीका है, "मुझे एक अच्छा साफ नया स्ट्रिंग मान बनाएं" केवल स्ट्रिंग झंडे के साथ और कोई संख्यात्मक झंडे नहीं।

मुझे यकीन है कि 99.9% नियम के लिए अन्य अजीब अपवाद हैं। ये कुछ हैं। उद्धरण हटाने से पहले, इस तरह अजीब बकवास की जांच के लिए एक सेकंड ले लो। यदि आप कानूनी उपयोग पर होते हैं, तो कृपया एक टिप्पणी जोड़ें जो कोट्स को एक व्यावहारिक क्लज के रूप में पहचानती है, और अस्तित्व के लिए अपना कारण देती है।

+0

पुन "यदि आप एक्सएस कोड के साथ काम कर रहे हैं जो फ़ंक्शन पर स्केलर तर्कों पर सेट किए गए झंडे को देखता है", मैंने पहले एक शुद्ध पर्ल उदाहरण दिखाया था। कुछ भी जो 'ref() 'का उपयोग करता है वह पर्याप्त होगा। – ikegami

6

इस मामले में डबल कोट्स अनावश्यक हैं। इसके अलावा, उनका उपयोग अक्षम है क्योंकि इससे मूल तारों की प्रतिलिपि बनाई जा सकती है।

हालांकि, कभी-कभी आप किसी ऑब्जेक्ट को "स्ट्रिंग" करने के लिए इस शैली का उपयोग करना चाह सकते हैं। उदाहरण के लिए, URI ojects stringification समर्थन करते हैं:

my $uri = URI->new("http://www.perl.com"); 
my $str = "$uri"; 
+0

यदि चेतावनियां सक्षम नहीं की गई हैं तो यह चुपचाप एक खाली स्ट्रिंग में 'undef' चालू कर देगी, है ना? मैं उस वैध उपयोग को कॉल नहीं करता हूं, हालांकि, मैं वैध होने के लिए चेतावनी के बिना कुछ भी नहीं मानूंगा। –

+0

@ एमयू बहुत छोटा है: हां, 'अपरिफ' '''' '' (चाहे चेतावनी सक्षम हो या नहीं) –

+0

लेकिन यह चेतावनी के साथ चुपचाप नहीं चलेगा, आपको "समामेलन में अनियमित मूल्य" शिकायत मिलेगी । –

6

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


यह मूल रूप में एक ही मूल्य के साथ एक नया स्ट्रिंग बनाने का प्रभाव पड़ता है, और है कि बहुत दुर्लभ परिस्थितियों में उपयोगी हो सकता है।

निम्नलिखित उदाहरण में, उप एक्स द्वारा संशोधन से $ x की सुरक्षा के लिए एक स्पष्ट प्रतिलिपि की जाती है क्योंकि उप इसके तर्क को संशोधित करता है।

$ perl -E' 
    sub f { $_[0] =~ tr/a/A/; say $_[0]; } 
    my $x = "abc"; 
    f($x); 
    say $x; 
' 
Abc 
Abc 

$ perl -E' 
    sub f { $_[0] =~ tr/a/A/; say $_[0]; } 
    my $x = "abc"; 
    f("$x"); 
    say $x; 
' 
Abc 
abc 

स्ट्रिंग की एक प्रतिलिपि बनाने के आधार पर, यह वस्तुओं stringifies। कोड के साथ व्यवहार करते समय यह उपयोगी हो सकता है जो इसके व्यवहार को बदलता है कि क्या यह तर्क एक संदर्भ है या नहीं।

निम्नलिखित उदाहरण में, स्पष्ट स्ट्रिंगफिकेशन किया जाता है क्योंकि require@INC स्ट्रिंग्स से अलग संदर्भों को संभालता है।

$ perl -MPath::Class=file -E' 
    BEGIN { $lib = file($0)->dir; } 
    use lib $lib; 
    use DBI; 
    say "ok"; 
' 
Can't locate object method "INC" via package "Path::Class::Dir" at -e line 4. 
BEGIN failed--compilation aborted at -e line 4. 

$ perl -MPath::Class=file -E' 
    BEGIN { $lib = file($0)->dir; } 
    use lib "$lib"; 
    use DBI; 
    say "ok"; 
' 
ok 
+0

पहला मामला स्पष्ट प्रतिलिपि के साथ "वर्कअराउंड @_ एलियासिंग" के रूप में वर्णित किया जा सकता है। मैं कोड में टिप्पणियां जोड़ने की सिफारिश करता हूं जो ऐसी चीजें करता है। – dolmen

+0

@ डॉल्मेन, उदाहरणों का विवरण जोड़ा गया। – ikegami

0

मेरा सिद्धांत हमेशा यह रहा है कि लोग बुरी आदतों वाले अन्य भाषाओं से आ रहे हैं। ऐसा नहीं है कि वे सोच रहे हैं "मैं हर समय डबल कोट्स का उपयोग करूंगा", लेकिन वे सिर्फ सोच नहीं रहे हैं!

मैं ईमानदार रहूंगा और कहूंगा कि मैं इस जाल में पड़ता था क्योंकि मैं जावा से पर्ल आया था, इसलिए मांसपेशी स्मृति वहां थी, और केवल फायरिंग रखी गई थी।

पर्लक्रिटिक ने अंततः मुझे आदत से बाहर कर दिया!

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

2

आपके मामले में उद्धरण पूरी तरह से बेकार हैं। हम यह भी कह सकते हैं कि यह गलत है क्योंकि यह मूर्खतापूर्ण नहीं है, जैसा कि अन्य ने लिखा था।

हालांकि एक चर को उद्धृत करना कभी-कभी आवश्यक हो सकता है: यह स्पष्ट रूप से चर के मान की स्ट्रिंग को ट्रिगर करता है। स्ट्रिंगफिकेशन कुछ मानों के लिए एक अलग परिणाम दे सकता है यदि मूल्यों को खो देता है तो मान दोहरी वर्ण होते हैं या यदि वे overload एड स्ट्रिंग के साथ मूल्यों को आशीर्वादित करते हैं।

यहाँ दोहरी वार्स के साथ एक उदाहरण है:

use 5.010; 
use strict; 
use Scalar::Util 'dualvar'; 

my $x = dualvar 1, "2"; 
say 0+$x; 
say 0+"$x"; 

आउटपुट:

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