2008-09-24 27 views
60

क्या कोई बता सकता है कि "0 लेकिन सत्य" स्ट्रिंग वास्तव में पर्ल में क्या है? जहां तक ​​मैं समझता हूं, यह एक पूर्णांक तुलना में शून्य के बराबर होता है, लेकिन जब बूलियन के रूप में उपयोग किया जाता है तो सत्य का मूल्यांकन करता है। क्या ये सही है? क्या यह भाषा का सामान्य व्यवहार है या क्या यह एक विशेष स्ट्रिंग है जिसे दुभाषिया में विशेष मामले के रूप में माना जाता है?पर्ल में "0 लेकिन सच" का क्या अर्थ है?

+11

स्ट्रिंग '" 0E0 "' दूसरा '0' लेकिन सत्य "जैसा है। कठोर कोडिंग होने के बजाय यह पर्ल के घातीय नोटेशन का एक परिणाम है। एक गैर-खाली, गैर-शून्य स्ट्रिंग के रूप में, यह सच है। एक संख्या के रूप में, यह 0 है। डीबीआई इसे 'execute' जैसी चीज़ों से रिटर्न वैल्यू के रूप में उपयोग करता है यह इंगित करने के लिए कि SQL कथन काम करता है, लेकिन कोई पंक्ति प्रभावित नहीं हुई थी। – Schwern

+0

मैं किसी संख्या में परिवर्तित होने पर चेतावनियों के लिए "0 लेकिन सत्य" के विशेष उपचार के कारण को समझता हूं, लेकिन मुझे अभी भी लगता है कि look_like_number * झूठी वापसी करनी चाहिए। – bart

उत्तर

55

यह भाषा का सामान्य व्यवहार है।

संख्या 0, तार '0' और "", खाली सूची (), और undef एक बूलियन संदर्भ में सभी झूठे हैं: perlsyn मैनपेज का हवाला देते हुए। अन्य सभी मूल्य सत्य हैं। ! या not द्वारा वास्तविक मान का नकारात्मक एक विशेष झूठा मान देता है। जब एक स्ट्रिंग के रूप में मूल्यांकन किया जाता है तो इसे "" के रूप में माना जाता है, लेकिन एक संख्या के रूप में, यह 0 के रूप में माना जाता है।

इस वजह से

, वहाँ एक सिस्टम कॉल 0 एक (सफल) वापसी मान के रूप में वापस जाने के लिए उम्मीद है कि से 0 वापस जाने के लिए एक तरीका हो, और वास्तव में एक झूठी प्रत्यावर्तित करके विफलता मामले संकेत करने के लिए एक तरह से छोड़ने के लिए की जरूरत है मूल्य। "0 but true" उस उद्देश्य को पूरा करता है।

+0

नाइट: '0 लेकिन सच' सिर्फ सिस्टम कॉल के लिए नहीं है। –

+14

कुछ मॉड्यूल स्ट्रिंग "0E0" का उपयोग करते हैं, जो 0 के रूप में मूल्यांकन करता है, लेकिन बुलियन के रूप में सत्य है। –

+5

ओएमजी पर्ल इतना अस्पष्ट है: ओ –

9

एक पूर्णांक संदर्भ में, यह 0 (स्ट्रिंग की शुरुआत में संख्यात्मक भाग) का मूल्यांकन करता है और शून्य है। एक स्केलर संदर्भ में, यह एक खाली मूल्य है, इसलिए यह सच है।

  • if (int("0 but true")) { print "zero"; }

    (कोई उत्पादन)

  • if ("0 but true") { print "true"; }

    (सच प्रिंट)

2

जब आप एक समारोह है कि या तो एक पूर्णांक मान देता है लिखना चाहते हैं , या झूठी या undef (यानी। त्रुटि मामले के लिए) तो आपको मान शून्य के लिए देखना होगा। इसे लौटाना गलत है और त्रुटि की स्थिति को इंगित नहीं करना चाहिए, इसलिए "0 लेकिन सत्य" लौटने से फ़ंक्शन रिटर्न वैल्यू सही हो जाता है, जबकि उस पर गणित किए जाने पर मान शून्य वापस गुजरता है।

44

साथ ही क्या अन्य लोगों ने कहा है, "0 but true" विशेष मामलों में है कि यह संख्यात्मक संदर्भ में चेतावनी दी है नहीं करता है:

$ perl -wle 'print "0 but true" + 3' 
3 
$ perl -wle 'print "0 but crazy" + 3' 
Argument "0 but crazy" isn't numeric in addition (+) at -e line 1. 
3 
3

"0 लेकिन सच है" किसी भी अन्य की तरह एक स्ट्रिंग है लेकिन पर्ल की वाक्य रचना की वजह से यह एक उपयोगी उद्देश्य, अर्थात् "झूठी" (पर्ल की आंखों में) के परिणामस्वरूप बिना किसी फ़ंक्शन से पूर्णांक शून्य लौटा सकता है।

और स्ट्रिंग को "0 लेकिन सत्य" नहीं होना चाहिए। बूलियन भावना में "0 लेकिन झूठी" अभी भी "सच" है।

पर विचार करें:

if(x) 

for x:  yields: 
1    -> true 
0    -> false 
-1   -> true 
"true"  -> true 
"false"  -> true 
"0 but true" -> true 
int("0 but true") ->false 

इस सब का नतीजा यह है आप कर सकते हैं:

sub find_x() 

और इस कोड को इसके उत्पादन के रूप में "0" प्रिंट कर सकेंगे:

if($x = find_x) 
{ 
    print int($x) . "\n"; 
} 
+0

क्या आप वाकई उस शब्दकोष के बारे में निश्चित हैं? ऐसा नहीं है जब मैं $ 'perl -wle 'print" true \ n "झूठ बोलता हूं;" ' – MarkHu

+0

मार्कहू, आप सही हैं, न तो कोई वास्तविक या गलत कीवर्ड है। मैंने मूल जवाब संपादित किया है। – Frosty

8

का अर्थ पर्ल (और सी से संबंधित अन्य भाषाओं) में झूठा है। अधिकांश भाग के लिए, यह एक उचित व्यवहार है। अन्य भाषाओं (उदाहरण के लिए लुआ) सच के रूप में व्यवहार करें और एक अन्य टोकन प्रदान करें (अक्सर शून्य या झूठी) एक गैर-सत्य मान का प्रतिनिधित्व करने के लिए।

एक मामला जहां पर्ल रास्ता इतना अच्छा काम नहीं करता है वह तब होता है जब आप किसी संख्या को वापस करना चाहते हैं या यदि फ़ंक्शन किसी कारण से विफल रहता है, तो झूठा मान। उदाहरण के लिए, यदि आप एक फ़ंक्शन लिखते हैं जो फ़ाइल से एक पंक्ति पढ़ता है और रेखा पर वर्णों की संख्या देता है।

while($c = characters_in_line($file)){ 
    ... 
}; 

सूचना है कि अगर एक विशेष लाइन पर वर्णों की संख्या 0 है, जबकि पाश फ़ाइल के अंत से पहले खत्म हो जाएगा: समारोह का एक आम उपयोग कुछ की तरह हो सकता है। तो characters_in_line फ़ंक्शन को विशेष केस 0 वर्ण होना चाहिए और '0 0 लेकिन सही' वापस करना चाहिए। इस तरह से कार्य में लूप के रूप में कार्य करेगा, लेकिन सही उत्तर भी इसे एक संख्या के रूप में उपयोग किया जाना चाहिए।

ध्यान दें कि यह भाषा के एक हिस्से में निर्मित नहीं है। इसके बजाय यह एक स्ट्रिंग को एक संख्या के रूप में समझने की पर्ल की क्षमता का लाभ उठाता है। तो इसके बजाय कभी-कभी अन्य डंक का उपयोग किया जाता है। उदाहरण के लिए डीबीआई"0E0" का उपयोग करता है। संख्यात्मक संदर्भ में मूल्यांकन करते समय, वे लौटते हैं, लेकिन बूलियन संदर्भ में, झूठी

+0

क्या 0 के लिए डिफ़ॉल्ट मान था या भाषाओं में गलत या गलत प्रोग्राम किया गया था? मुझे समझ में नहीं आता कि क्यों कोई अलग-अलग भाषाओं के बीच अलग होना चाहता है। –

+0

हालांकि 0 भाषाओं में झूठी और 1 सच नहीं है? – bobtheboy

23

आप स्ट्रिंग "0E0" used in Perl code भी देख सकते हैं, और इसका मतलब वही बात है, जहां 0E0 का अर्थ केवल घातीय नोटेशन में लिखा गया है। हालांकि, चूंकि पर्ल केवल "0", या 'गलत के रूप में अनिश्चित मानता है, यह एक बुलियन संदर्भ में सत्य का मूल्यांकन करता है।

3

"0 लेकिन सच है" का एक और उदाहरण:

DBI मॉड्यूल अद्यतन के लिए एक वापसी मान के रूप में "0E0" का उपयोग करता है या प्रश्न है कि किसी भी रिकॉर्ड को प्रभावित नहीं किया DELETE। यह एक बूलियन संदर्भ में सत्य का मूल्यांकन करता है (यह दर्शाता है कि क्वेरी ठीक से निष्पादित की गई थी) और 0 को संख्यात्मक संदर्भ में इंगित करता है कि क्वेरी द्वारा कोई रिकॉर्ड नहीं बदला गया था।

3

मैं सिर्फ सबूत पाया गया कि स्ट्रिंग "0 लेकिन सच" actially कुछ लोगों को यहाँ पहले से ही उत्तर की तरह, दुभाषिया में बनाया गया है:

$ strings /usr/lib/perl5/5.10.0/linux/CORE/libperl.so | grep -i true 
Perl_sv_true 
%-p did not return a true value 
0 but true 
0 but true 
6

चीज़ें है कि झूठे हैं:

  • ""
  • "0"
  • चीजें जो उनको स्ट्रिंग करती हैं।

"0 but true" उनमें से एक नहीं है, इसलिए यह गलत नहीं है।

इसके अलावा, पर्ल "0 but true" लौटाता है जहां सिग्नल को इंगित करने के लिए एक संख्या अपेक्षित होती है कि यह शून्य हो गया हो। sysseek ऐसे फ़ंक्शन का एक उदाहरण है। चूंकि मान को एक संख्या के रूप में उपयोग करने की उम्मीद है, इसलिए पर्ल को इसे एक संख्या माना जाने के लिए कोड किया गया है। नतीजतन, जब कोई संख्या के रूप में उपयोग किया जाता है, तो कोई चेतावनी जारी नहीं की जाती है, और looks_like_number("0 but true") सत्य लौटाता है।

अन्य "असली शून्य" http://www.perlmonks.org/?node_id=464548 पर पाए जा सकते हैं।

+3

लेकिन यह जवाब नहीं देता है कि 'looks_like_number (" 0 लेकिन सत्य ") क्यों सत्य है, जबकि' looks_like_number ("0 लेकिन foobar") 'गलत है। – friedo

+0

@ फ़्रीडो, पर्ल एक संख्या के रूप में "0 लेकिन foobar" वापस नहीं लौटाता है। – ikegami

+0

@ फ़्रीडो, क्या आप वास्तव में पूछ रहे हैं कि क्यों पर्ल को शून्य की वापसी करने की आवश्यकता होगी, लेकिन सच का मूल्यांकन किया जाए? ऐसा इसलिए होता है जब शून्य संभव संभावित मूल्य होने पर कोई फ़ंक्शन सफल हो जाता है तो आप आसानी से मूल्यांकन कर सकते हैं। [sysseek] (http://perldoc.perl.org/functions/sysseek.html) एक उदाहरण है। – ikegami

51

क्योंकि यह पर्ल कोर में इसे एक संख्या के रूप में पेश करने के लिए हार्डकोड किया गया है। यह पर्ल के सम्मेलनों और ioctl के सम्मेलनों को एक साथ खेलने के लिए एक हैक है; perldoc -f ioctl से:

इस प्रकार

ioctl (और fcntl) की वापसी के मूल्य के रूप में:

if OS returns:  then Perl returns: 

    -1    undefined value 
    0    string "0 but true" 
anything else  that number 

इस प्रकार पर्ल विफलता पर सफलता पर सच और झूठी देता है, अभी तक आप अभी भी आसानी से वास्तविक मूल्य निर्धारित कर सकते हैं

$retval = ioctl(...) || -1; 
printf "System returned %d\n", $retval; 

विशेष स्ट्रिंग "0 but true" है: ऑपरेटिंग सिस्टम द्वारा दिया -w शिकायतें से अनुचित संख्यात्मक रूपांतरणों के बारे में छूट।

+12

भी utctl, semctl, sysseek, और विभिन्न CPAN मॉड्यूल द्वारा उपयोग किया जाता है। "इसे एक संख्या के रूप में मानें" भ्रामक है; "0 xxx", "foo", या "123profit" को संख्यात्मक संदर्भ में संख्याओं के रूप में भी माना जाता है; "0 लेकिन सत्य" के बारे में विशेष बात यह है कि यह जानबूझकर चेतावनी का कारण नहीं बनता है। – ysth

+0

आप पाएंगे कि रिलाप्स जैसी चीजों से विशेष परिभाषित नल स्ट्रिंग रिटर्न भी एक वैध संख्या है: 'perl -wle' printf "% d \ n", 4> 5'' 0 * sans * शिकायत उत्पन्न करता है। – tchrist

+0

एफडब्ल्यूआईडब्लू: पर्ल डीबीआई मॉड्यूल '0 लेकिन 0' के भिन्नता के रूप में '0E0' का उपयोग करता है। –

11

यह पर्ल के स्रोत कोड में विशेष रूप से Perl_grok_number_flags in numeric.c में हार्ड-कोड किया गया है।

उस कोड को पढ़कर मैंने पाया कि स्ट्रिंग "अनंतता" (केस असंवेदनशील) look_like_number परीक्षण भी पास करती है। मुझे यह नहीं पता था।

+1

कुछ सी पुस्तकालय "इन्फिनिटी" (या "+ इन्फिनिटी" या "-इफिनिटी") का उपयोग "इन्फ" की विविधता के बजाय फ्लोटिंग-पॉइंट अनंतता की स्ट्रिंग के रूप में करते हैं। – hobbs

32

मूल्य 0 but true पर्ल में एक विशेष मामला है। यद्यपि आपकी केवल प्राणियों की आंखों के लिए, यह एक संख्या की तरह नहीं दिखता है, बुद्धिमान और सभी जानते हैं कि पर्ल समझता है कि यह वास्तव में एक संख्या है।

इसे इस तथ्य के साथ करना है कि जब एक पर्ल सबराउटिन 0 मान देता है, तो यह माना जाता है कि दिनचर्या विफल हो जाती है या झूठी मान लौटा दी जाती है।

कल्पना कीजिए मैं एक सबरूटीन कि दो संख्याओं का योग देता है:

die "You can only add two numbers\n" if (not add(3, -2)); 
die "You can only add two numbers\n" if (not add("cow", "dog")); 
die "You can only add two numbers\n" if (not add(3, -3)); 

पहले बयान मर नहीं करेगा क्योंकि सबरूटीन एक 1 वापस आ जाएगी। अच्छी बात है। दूसरा कथन मर जाएगा क्योंकि subroutine गाय से कुत्ते जोड़ने में सक्षम नहीं होगा।

और, तीसरा बयान?

हम्म, मैं -3 जोड़ सकता हूं। मुझे बस 0 मिल गया है, लेकिन फिर मेरा प्रोग्राम मर जाएगा भले ही add सबराउटिन काम करता है!

इस के आसपास पाने के लिए, पर्ल 0 but true पर एक संख्या होने पर विचार करता है। यदि मेरा सबराउटिन न केवल देता है, लेकिन 0 लेकिन सही, मेरा तीसरा कथन काम करेगा।

लेकिन 0 है लेकिन वास्तविक एक संख्यात्मक शून्य है? इन्हें आजमाएं:

my $value = "0 but true"; 
print qq(Add 1,000,000 to it:) . (1_000_000 + $value) . "\n"; 
print "Multiply it by 1,000,000: " . 1_000_000 * $value . "\n"; 

हाँ, यह शून्य है!

index सबराउटिन पर्ल का एक बहुत पुराना टुकड़ा है और 0 की अवधारणा से पहले अस्तित्व में था लेकिन सच आसपास था। यह स्ट्रिंग में स्थित सबस्ट्रिंग की स्थिति वापस जाने के लिए लगता है:

index("barfoo", "foo"); #This returns 3 
index("barfoo", "bar"); #This returns 0 
index("barfoo", "fu"); #This returns ...uh... 

पिछले बयान देता है एक -1। जिसका अर्थ है कि मैंने यह किया:

if ($position = index($string, $substring)) { 
    print "It worked!\n"; 
} 
else { 
    print "If failed!\n"; 
} 

जैसा कि मैं सामान्य रूप से मानक कार्यों के साथ करता हूं, यह काम नहीं करेगा। अगर मैंने दूसरे कथन में "बारफू" और "बार" का इस्तेमाल किया, तो else खंड निष्पादित होगा, लेकिन अगर मैंने तीसरे में "बारफू" और "फू" का उपयोग किया था, तो if खंड निष्पादित होगा। मैं क्या चाहता हूँ नहीं।

हालांकि, अगर index सबरूटीन लौटे 0 लेकिन सच दूसरा बयान और undef तीसरे बयान के लिए के लिए, मेरे if/else खंड काम किया होता।

1

स्ट्रिंग `` 0 लेकिन सच है '' अभी भी एक विशेष मामला है:

for arg in "'0 but true'" "1.0*('0 but true')" \ 
      "1.0*('0 but false')" 0 1 "''" "0.0" \ 
      "'false'" "'Ja'" "'Nein'" "'Oui'" \ 
      "'Non'" "'Yes'" "'No'" ;do 
    printf "%-32s: %s\n" "$arg" "$(
     perl -we ' 
      my $ans=eval $ARGV[0]; 
      $ans=~s/^(Non?|Nein)$//; 
      if ($ans) { 
       printf "true: |%s|\n",$ans 
      } else { 
       printf "false: |%s|", $ans 
      };' "$arg" 
     )" 
    done 

निम्नलिखित दे: (ध्यान दें `` चेतावनी '!')

'0 but true'     : true: |0 but true| 
1.0*('0 but true')    : false: |0| 
Argument "0 but false" isn't numeric in multiplication (*) at (eval 1) line 1. 
1.0*('0 but false')    : false: |0| 
0        : false: |0| 
1        : true: |1| 
''        : false: || 
0.0        : false: |0| 
'false'       : true: |false| 
'Ja'       : true: |Ja| 
'Nein'       : false: || 
'Oui'       : true: |Oui| 
'Non'       : false: || 
'Yes'       : true: |Yes| 
'No'       : false: || 

... और आरटीएफएम को मत भूलना!

man -P'less +"/0 but [a-z]*"' perlfunc 

     ... "fcntl". Like "ioctl", it maps a 0 return from the system call 
      into "0 but true" in Perl. This string is true in boolean 
      context and 0 in numeric context. It is also exempt from the 
      normal -w warnings on improper numeric conversions. ... 
संबंधित मुद्दे