2012-03-20 33 views
5

मैं एक पीएलएल संरचना से JSON के समान कुछ आउटपुट करने के लिए एक चीज़ लिख रहा हूं। मैं इस तरह से व्यवहार करने के हवाले हैं:क्या कोई स्केलर स्ट्रिंग किया गया है या नहीं, यह जांचने का कोई तरीका है?

"string" outputs "string" 
"05" outputs "05" 
"5" outputs "5" 
5 outputs 5 
05 outputs 5, or 05 would be acceptable 

JSON :: XS जांच करना है कि एक अदिश "stringified" किया गया है या नहीं, जो मुझे लगता है कि बहुत अच्छा है द्वारा इस संभालती है। लेकिन मुझे एक्सएस लिखने के बिना खुद को यह परीक्षण करने का कोई तरीका नहीं मिल रहा है, जिसे मैं टालना चाहता हूं। क्या यह संभव है? मुझे स्कालर :: Util :: looks_like_number, आदि के बारे में विशाल पैडेंट्री के बिना सीपीएएन पर कहीं भी नहीं मिल सकता है जो पूरी तरह से नहीं चाहता है। एकमात्र स्टॉपगैप मैं पा सकता हूं डेवेल :: पीक, जो बुराई महसूस करता है। और यह भी, बस JSON :: XS की तरह, मैं ठीक इस secenario साथ हूँ:

my $a = 5; 
print $a."\n"; 
# now $a outputs "5" instead of 5) 

उत्तर

5

B::svref_2object के उत्पादन का निरीक्षण करें:

use B; 
($x, $y, $z) = ("5", 5, 5.0); 

print ref(B::svref_2object(\$x)), "\n"; 
print ref(B::svref_2object(\$y)), "\n"; 
print ref(B::svref_2object(\$z)), "\n"; 

आउटपुट:

B::PV 
B::IV 
B::NV 

या, Ikegami पता चलता है के रूप में, यदि आप बल्कि pPOK झंडा देखने चाहते हैं:

if (B::svref_2object(\$x)->FLAGS & B::SVp_POK) { 
    print "I guess \$x is stringy\n"; 
} 
+0

एसवी प्रकार के साथ इसका कोई लेना-देना नहीं है। इसे पीपीओके ध्वज के साथ करना है। – ikegami

+0

उदाहरण के लिए, 'मेरा $ x = "" देखें; $ X = 5; मेरा $ वाई = 5; "" $ Y;। '। दोनों पीवीआईवी हैं, लेकिन केवल एक "स्ट्रिंग" है। – ikegami

+0

मैंने अभी भी यह देखा है। यह अच्छा होगा अगर बी ने वास्तव में जो कुछ प्रदान किया वह सूचीबद्ध है! दुर्भाग्यवश, ऐसा लगता है कि 'SvGETMAGIC' उपलब्ध नहीं है। – ikegami

2

यह शायद सबसे अच्छा तरीका नहीं है, लेकिन अगर JSON आप क्या चाहते हैं करता है, यह क्यों उपयोग नहीं?

sub is_stringy { 
    encode_json([$_[0]]) =~ /["']/ 
} 

is_stringy(5);  # undef 
is_string("5");  # 1 
+0

शायद यह है कि अगर मैं बेहतर उत्तर नहीं पा रहा हूं तो मैं ऐसा करूँगा। हालांकि यह निश्चित रूप से अपमानजनक लगता है। मैं सिर्फ जेएसओएन :: एक्सएस के स्केलर आउटपुट को रखता हूं, लेकिन दुर्भाग्यवश जो मैं आउटपुट कर रहा हूं वह JSON नहीं है और इसमें अलग-अलग भागने के नियम हैं। – Yobert

4

आप यह इतना एक नंबर नहीं रह गया है निम्नलिखित का उपयोग करके stringified गया प्रतीत होता है बना सकते हैं:

$x = 0+$x; 

उदाहरण के लिए,

$ perl -MJSON::XS -E' 
    $_ = 4; 
    say encode_json([$_]); # [4] 
    "".$_; 
    say encode_json([$_]); # ["4"] 
    $_ = 0 + $_; 
    say encode_json([$_]); # [4] 
' 

का पता लगा रहा है कि क्या कुछ stringified कर दिया गया है मुश्किल है, क्योंकि JSON :: एक्सएस पर्ल आंतरिक में देख रहा है। निम्न में से एक का उपयोग कर सकता:

sub is_stringy { 
    { no warnings 'void'; "".$_[0]; } 
    return 1; 
} 

लेकिन मुझे लगता है कि तुम क्या चाहते हो :) मैं कैसे कुछ XS कोड लिखने के बिना "भ्रष्टाचार" पता लगाने के लिए पता नहीं है नहीं लगता। आप क्या जानना चाहते हैं कि SvPOKp स्केलर के लिए सच है (स्केलर पर SvGETMAGIC पर कॉल करने के बाद)।

use Inline C => <<'__EOI__'; 

    SV* is_stringy(SV* sv) { 
     SvGETMAGIC(sv); 
     return SvPOKp(sv) ? &PL_sv_yes : &PL_sv_no; 
    } 

__EOI__ 

$_ = 4; 
say is_stringy($_) ?1:0; # 0 
{ no warnings 'void'; "".$_; } 
say is_stringy($_) ?1:0; # 1 
$_ = 0+$_; 
say is_stringy($_) ?1:0; # 0 

ओओ! ऐसा लगता है कि BSVp_POK प्रदान करता है, तो यह (लगभग) नई XS कोड लिखने

use B qw(svref_2object SVp_POK); 

sub is_stringy { 
    my ($s) = @_; 
    my $sv = svref_2object(\$s); 
    #$sv->GETMAGIC(); # Not available 
    return $sv->FLAGS & SVp_POK; 
} 

कॉल करने के लिए SvGETMAGIC कमियां हैं असमर्थ होने के नाते बिना किया जा सकता है, लेकिन यह समय के लगभग सभी काम करेंगे।

+0

@Yobert, फिर से अपडेट किया गया। – ikegami

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

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