2016-01-15 2 views
10

यह स्क्रिप्ट:

#!/usr/bin/perl 
use strict; 
use warnings; 

my ${fh}; 

open($fh, '<', "some_file.txt") or die "fail\n"; 

while(my $line = <${fh}>) { 
    print $line; 
} 
close $fh; 

आउटपुट:

GLOB(0x5bcc2a0) 

क्यों इस उत्पादन है?

यदि मैं <${fh}> से <$fh> बदलता हूं, तो यह अपेक्षित रूप से some_file.txt लाइन प्रिंट करेगा। मैंने सोचा कि ब्रेसिज़ का उपयोग चर नामों को सीमित करने के लिए किया जा सकता है, और my ${var}my $var जैसा ही होगा।

क्या ऐसे अन्य परिदृश्य हैं जहां {} को एक परिवर्तनीय नाम के आसपास जोड़ना समस्याएं पैदा करता है?

मैंने Red Hat और Cygwin Perl 5.14 पर पर्ल 5.8.8 पर कोशिश की।

+0

ऐसे कई परिदृश्य हैं जहां '{}' पार्स बदलना शामिल है, उदा। '" $ foobar "' बनाम '" $ {foo} बार "', '" $ foo :: bar "' बनाम '" $ {foo} :: bar "', '" $ foo's bar "' बनाम। '" $ {foo} की बार "', '" $ foo [0] "' बनाम '" $ {foo} [0] "'। लेकिन मुझे लगता है कि आप स्ट्रिंग इंटरपोलेशन के अलावा स्थितियों के बारे में पूछ रहे हैं? – ThisSuitIsBlackNot

+0

@ThisSuitIsBlack नहीं आपने सही अनुमान लगाया है। महान जवाब भी! – chilemagic

उत्तर

18

<> पर अनुभाग से perlop में:

क्या कोण कोष्ठक शामिल एक सरल अदिश चर (उदाहरण, $foo के लिए) है, तो उस चर filehandle के नाम इनपुट करने के लिए, से शामिल है या इसका टाइपग्लोब, या इसका संदर्भ। उदाहरण के लिए:

$fh = \*STDIN; 
$line = <$fh>; 

क्या कोण कोष्ठक के भीतर है है न तो एक filehandle है और न ही एक सरल अदिश चर एक filehandle नाम, typeglob, या typeglob संदर्भ युक्त, यह एक फ़ाइल नाम पैटर्न के रूप में व्याख्या की है, तो globbed किया जाना है, और या तो एक संदर्भ के आधार पर, फ़ाइल नामों की सूची या सूची में अगला फ़ाइल नाम वापस कर दिया गया है। यह भेद अकेले वाक्य रचनात्मक आधार पर निर्धारित है। इसका मतलब है कि <$x> एक अप्रत्यक्ष हैंडल से हमेशा readline() है, लेकिन <$hash{key}> हमेशा glob() है। ऐसा इसलिए है क्योंकि $x एक साधारण स्केलर चर है, लेकिन $hash{key} नहीं है - यह एक हैश तत्व है। यहां तक ​​कि <$x > (अतिरिक्त स्थान नोट करें) glob("$x ") के रूप में माना जाता है, readline($x) नहीं।

आप B::Concise के साथ इस देख सकते हैं:

$ perl -MO=Concise -e'<$fh>' 
5 <@> leave[1 ref] vKP/REFC ->(end) 
1  <0> enter ->2 
2  <;> nextstate(main 1 -e:1) v:{ ->3 
4  <1> readline[t1] vK*/1 ->5 
-  <1> ex-rv2sv sK/1 ->4 
3   <$> gvsv(*fh) s ->4 
-e syntax OK 

$ perl -MO=Concise -e'<${fh}>' 
6 <@> leave[1 ref] vKP/REFC ->(end) 
1  <0> enter ->2 
2  <;> nextstate(main 70 -e:1) v:{ ->3 
5  <@> glob[t1] vK/1 ->6 
-  <0> ex-pushmark s ->3 
-  <1> ex-rv2sv sK/1 ->4 
3   <$> gvsv(*fh) s ->4 
4  <$> gv(*_GEN_0) s ->5 
-e syntax OK 
11
  • <> मतलब है readline(ARGV)
  • <IDENTIFIER> मतलब है readline(IDENTIFIER)
  • <$IDENTIFIER>readline($IDENTIFIER)
  • <...> (कुछ और) का अर्थ है मुझे ans glob(qq<...>)

तो,

  • <$fh> मतलब है readline($fh)
  • <${fh}> मतलब है glob(qq<${fh}>), जो glob("$fh") के समान है।

glob पैटर्न से कई स्ट्रिंग या फ़ाइल नाम उत्पन्न करने के लिए उपयोग किया जाता है।

इस मामले में, फ़ाइल हैंडल की स्ट्रिंगफिकेशन GLOB(0x5bcc2a0) है। यह ग्लोब को पारित किया जा रहा है, लेकिन उनमें से कोई भी पात्र glob के लिए विशेष अर्थ नहीं है, इसलिए glob बस उस स्ट्रिंग को वापस कर देता है।

+0

तो मूल रूप से '<>' को पूर्ण वर्ण स्तर पर परिभाषित किया गया है ... वाह, सीएस झुकाव नौकरी! – Kaz

+4

@ काज़, आपको वह कहाँ मिला? मेरी पोस्ट ने इसे टोकन के संदर्भ में परिभाषित किया। यहां तक ​​कि अगर उसने उप-भाषा (जैसे 'm //', 'tr ///',' sprintf' और 'glob' do) का उपयोग किया है, तो मुझे नहीं लगता कि यह आपके गांठों को गाँठ में क्यों ले जाता है। – ikegami

+0

दूसरे उत्तर में यह नोट किया गया है (दस्तावेज़ीकरण से उद्धृत) कि '<$x > '' <$x> 'से बिल्कुल अलग है। – Kaz

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