2011-09-15 11 views
7

में एक चर का प्रकार निर्धारित करें मैं टीसीएल में एक चर के प्रकार को खोजने का एक तरीका ढूंढ रहा हूं। उदाहरण के लिए यदि मेरे पास परिवर्तनीय $ ए है और मैं गीलेर को जानना चाहता हूं तो यह एक पूर्णांक है।टीसीएल

मैं उपयोग कर रहा है निम्नलिखित अब तक:

if {[string is boolean $a]} { 
    #do something 
    } 

और इस महान काम करने के लिए लगता है निम्नलिखित प्रकार के लिए: alnum, अल्फा, ascii, बूलियन, नियंत्रण, अंकों, डबल, झूठे, ग्राफ, पूर्णांक, निचला, प्रिंट, punct, अंतरिक्ष, सत्य, ऊपरी, wordchar, xdigit

हालांकि यह मुझे यह बताने में सक्षम नहीं है कि मेरा चर एक सरणी, एक सूची या शब्दकोश हो सकता है या नहीं। क्या किसी को यह बताने का तरीका पता है कि कोई वैरिएबल उन तीनों में से एक है या नहीं?

अग्रिम

+0

टीसीएल के किस संस्करण के लिए आपको इसकी आवश्यकता है? –

+3

क्या आप समझा सकते हैं कि आपको इसे पहले स्थान पर क्यों चाहिए? मेरा मतलब है, चूंकि टीसीएल अनिवार्य रूप से एक टाइपहीन भाषा है जो आप पूछते हैं कि परेशानी के लिए पूछना पसंद है। – kostix

+0

@ कोस्टिक्स, बिल्कुल। मुझे इसकी आवश्यकता है एक प्रक्रिया बनाने के लिए जिसमें एक शब्दकोश जेएसओएन में पार्स किया गया है। जेएसओएन में उदाहरण के लिए स्ट्रिंग्स "" से घिरे हुए हैं जबकि पूर्णांक नहीं हैं। इसके अलावा यदि शब्दकोश में एक और शब्दकोश होना था, तो उस शब्दकोश को JSON ऑब्जेक्ट के भीतर अपना स्वयं का JSON ऑब्जेक्ट प्राप्त करना चाहिए। – Tom

उत्तर

0

धन्यवाद सरणियों आप चाहते हैं array exists dicts के लिए आप चाहते हैं dict exists

एक सूची मुझे नहीं लगता कि एक 8.5 से पहले रास्ते में बनाया ?, वहाँ http://wiki.tcl.tk/440 से है वहाँ के लिए

के लिए

proc isalist {string} { 
    return [expr {0 == [catch {llength $string}]}] 
} 
+0

धन्यवाद धन्यवाद :) क्या आप समझा सकते हैं कि आप इस मामले में कैसे इस्तेमाल करेंगे! मैंने इसे इस तरह उपयोग करने की कोशिश की है: यदि {[dict$ $ testData2 nullval]} { #do कुछ } परन्तु यदि चर एक नियम नहीं है तो यह त्रुटियों को वापस कर देगा। – Tom

+1

@ टॉम, उस मामले में मैं आपके कथन को 'कैच' में लपेटूंगा, जो आपको उस मामले को संसाधित करने की अनुमति देगा जहां चर एक नियम नहीं है। – TrojanName

11

Tcl के चर की जरूरत नहीं है प्रकार (या नहीं, वे वास्तव में चर के एक साहचर्य सरणी हो के लिए छोड़कर - यानी, $foo(bar) सिंटैक्स का उपयोग - के लिए आर जो आप array exists का उपयोग करते हैं) लेकिन टीसीएल के मूल्य करते हैं। खैर, कुछ हद तक। टीसीएल विभिन्न प्रकारों के बीच मूल्यों को बदल सकता है क्योंकि यह फिट दिखाई देता है और इस जानकारी का खुलासा नहीं करता है [*]; आप वास्तव में यह कर सकते हैं कि एक मूल्य किसी विशेष प्रकार के अनुरूप है या नहीं।

इस तरह की अनुरूपता के चेक के साथ किया जाता है string is (जहां -strict विकल्प, बदसूरत ऐतिहासिक कारणों के लिए की जरूरत है):

if {[string is integer -strict $foo]} { 
    puts "$foo is an integer!" 
} 

if {[string is list $foo]} { # Only [string is] where -strict has no effect 
    puts "$foo is a list! (length: [llength $foo])" 
    if {[llength $foo]&1 == 0} { 
     # All dictionaries conform to lists with even length 
     puts "$foo is a dictionary! (entries: [dict size $foo])" 
    } 
} 

ध्यान दें कि सभी मानों को स्ट्रिंग्स के प्रकार के अनुरूप; टीसीएल के मूल्य हमेशा क्रमिक हैं।

[टिप्पणियों से संपादित करें]: जेएसओएन क्रमिकरण के लिए, "सही" क्रमिकरण (सख्ती से, स्ट्रिंग में सब कुछ डालने से टीसीएल के परिप्रेक्ष्य से सही होगा) लेकिन यह अन्य भाषाओं के लिए बिल्कुल उपयोगी नहीं है) टीसीएल 8.6 के साथ। यह करने के लिए कोड, मूल रूप से Rosetta Code पर तैनात है:

package require Tcl 8.6 

proc tcl2json value { 
    # Guess the type of the value; deep *UNSUPPORTED* magic! 
    regexp {^value is a (.*?) with a refcount} \ 
     [::tcl::unsupported::representation $value] -> type 

    switch $type { 
     string { 
      # Skip to the mapping code at the bottom 
     } 
     dict { 
      set result "{" 
      set pfx "" 
      dict for {k v} $value { 
       append result $pfx [tcl2json $k] ": " [tcl2json $v] 
       set pfx ", " 
      } 
      return [append result "}"] 
     } 
     list { 
      set result "\[" 
      set pfx "" 
      foreach v $value { 
       append result $pfx [tcl2json $v] 
       set pfx ", " 
      } 
      return [append result "\]"] 
     } 
     int - double { 
      return [expr {$value}] 
     } 
     booleanString { 
      return [expr {$value ? "true" : "false"}] 
     } 
     default { 
      # Some other type; do some guessing... 
      if {$value eq "null"} { 
       # Tcl has *no* null value at all; empty strings are semantically 
       # different and absent variables aren't values. So cheat! 
       return $value 
      } elseif {[string is integer -strict $value]} { 
       return [expr {$value}] 
      } elseif {[string is double -strict $value]} { 
       return [expr {$value}] 
      } elseif {[string is boolean -strict $value]} { 
       return [expr {$value ? "true" : "false"}] 
      } 
     } 
    } 

    # For simplicity, all "bad" characters are mapped to \u... substitutions 
    set mapped [subst -novariables [regsub -all {[][\u0000-\u001f\\""]} \ 
     $value {[format "\\\\u%04x" [scan {& } %c]]}]] 
    return "\"$mapped\"" 
} 

चेतावनी: ऊपर कोड समर्थित नहीं है। यह गंदे हैक्स पर निर्भर करता है। चेतावनी के बिना तोड़ने के लिए उत्तरदायी है। (लेकिन यह काम करते हैं। Tcl 8.5 Porting एक छोटे सी विस्तार की आवश्यकता होगी है प्रकार एनोटेशन बाहर पढ़ने के लिए।)


[*] कड़ाई से, यह एक असमर्थित इंटरफ़ेस वर्तमान प्रकार एनोटेशन की खोज के लिए प्रदान करता है 8.6 में एक मूल्य के - ::tcl::unsupported::representation के हिस्से के रूप में - लेकिन वह जानकारी जानबूझकर मानव-पठनीय रूप में है और घोषणा के बिना परिवर्तन के अधीन है। यह डिबगिंग के लिए है, कोड नहीं। इसके अलावा, टीसीएल आंतरिक रूप से कई अलग-अलग प्रकारों का उपयोग करता है (उदा।, कैश किए गए कमांड और वेरिएबल नाम) कि आप सामान्य परिस्थितियों में जांच नहीं करना चाहेंगे; बातें नहीं बल्कि हुड के नीचे जटिल हैं ... अगर एक चर एक सरणी है

+0

प्रतिक्रिया के लिए धन्यवाद, लेकिन ऐसा लगता है कि यह काम नहीं करेगा। यदि {{स्ट्रिंग सूची $ foo]} {part में है। स्ट्रिंग्स जो एकाधिक शब्दों को पकड़ती हैं उन्हें अल सूची भी दिखाई देती है।इसके अलावा यदि मेरे पास एक सूची भी थी जिसमें आइटम भी शामिल था, तो यह कोड हमेशा इसे एक शब्दकोश के रूप में वर्गीकृत करेगा। मुझे यकीन नहीं है कि मैं जो करने की कोशिश कर रहा हूं वह भी संभव है, हालांकि, आपका कोड शायद सबसे अच्छा संभव समाधान भी हो सकता है। – Tom

+1

@ टॉम, ऐसा इसलिए है क्योंकि एकाधिक शब्दों वाले स्ट्रिंग को 'सूची' कमांड के साथ बनाए गए चर से अलग नहीं किया जाता है। उदाहरण के लिए, इसे आज़माएं: foo "ab bb dd" सेट करें; lindex $ foo 1 – TrojanName

+0

'स्ट्रिंग सूची है' 8.5 या 8.6 ?, जहां तक ​​मैं देख सकता हूं कि यह टॉम के लिए उपलब्ध नहीं हो सकता है? –

0

निर्धारित करने के लिए:

proc is_array {var} { 
    upvar 1 $var value 
    if {[catch {array names $value} errmsg]} { return 1 } 
    return 0 
} 

# How to use it 
array set ar {} 
set x {1 2 3} 
puts "ar is array? [is_array ar]"; # ar is array? 1 
puts "x is array? [is_array x]"; # x is array? 0 
+0

आप गायब हैं '[सरणी मौजूद है varname] '- http://www.tcl.tk/man/tcl8.5/TclCmd/array.htm –

+0

जेके पहले से ही वर्णित सरणी मौजूद है, मैं बस ऑफर करना चाहता हूं चीजों को करने का एक अलग तरीका। –

+1

मैं देखता हूं। सरणी नामों की सूची उत्पन्न करना (बस उन्हें फेंकने के लिए) महंगा है: आप इसके बजाय 'सरणी आकार' चाहते हैं। –

1

आप JSON के साथ सौदा करना चाहते हैं तो मैं अत्यधिक तुम Tcl विकि पर JSON पृष्ठ को पढ़ने का सुझाव: http://wiki.tcl.tk/json

उस पृष्ठ पर मैंने एक साधारण फ़ंक्शन पोस्ट किया जो एक प्रारूपण वर्णनकर्ता को JSON स्ट्रिंग को Tcl मानों को संकलित करता है। मुझे उस पृष्ठ पर बहुत ही जानकारीपूर्ण चर्चा भी मिलती है।

3

अन्य सभी उत्तर बहुत उपयोगी जानकारी प्रदान करते हैं, लेकिन यह कुछ ध्यान देने योग्य है कि बहुत से लोग पहले ग्रोक नहीं लगते हैं।

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

string is integer $a 

आप

नहीं कह रहे हैं $ में मूल्य एक एक पूर्णांक

है क्या आप पूछ रहे हैं है

क्या मैं $ 1 में एक पूर्णांक

के रूप में मान का उपयोग कर सकता हूं

जब आप "यह एक पूर्णांक" के आधार पर सोच रहे हैं तो दोनों प्रश्नों के बीच अंतर पर विचार करना उपयोगी है। प्रत्येक पूर्णांक भी एक वैध सूची (एक तत्व का) है ... इसलिए यह can be used या तो दोनों के रूप में और string is आदेश सत्य वापस आ जाएंगे (जैसा कि कई अन्य एक पूर्णांक के लिए होंगे)।

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