2012-06-20 23 views
6

इस सवाल का मूल कारण पर्ल के लिए एक नए विकल्प/तर्क प्रसंस्करण मॉड्यूल (OptArgs) के लिए परीक्षण लिखने का मेरा प्रयास है। इसमें निश्चित रूप से @ARGV पार्सिंग शामिल है जो मैं this प्रश्न के उत्तर के आधार पर कर रहा हूं। यह उन प्रणालियों पर ठीक काम करता है जहां I18N :: Langinfo :: CODESET परिभाषित किया गया है [1]।पर्ल में मैं बाहरी आदेशों के लिए यूनिकोड तर्क कैसे पास करूं?

सिस्टम पर जहां langinfo(CODESET) उपलब्ध नहीं है, मैं कम से कम मनाए गए व्यवहार के आधार पर सर्वोत्तम प्रयास करना चाहता हूं। हालांकि अब तक मेरे परीक्षणों से संकेत मिलता है कि कुछ सिस्टम मैं को बाहरी स्क्रिप्ट के लिए एक यूनिकोड तर्क ठीक से नहीं दे सकता।

मैं कहाँ "test_script" एक पर्ल स्क्रिप्ट है कि केवल करता है विभिन्न प्रणालियों पर निम्नलिखित की तरह कुछ चलाने में कामयाब रहे एक print Dumper(@ARGV):

use utf8; 
my $utf8 = '¥'; 
my $result = qx/$^X test_script $utf8/; 

क्या मैं ने पाया है कि FreeBSD पर test_script बाइट्स प्राप्त करता है जो पर्ल के आंतरिक प्रारूप में डीकोड किया जा सकता है। हालांकि ओपनबीएसडी और सोलारिस test_script पर स्ट्रिंग "\x{fffd}\x{fffd}" प्राप्त होता है जिसमें केवल यूनिकोड प्रतिस्थापन वर्ण (दो बार?) होता है।

मुझे qx ऑपरेटर के अंतर्गत तंत्र को नहीं पता है। मुझे लगता है कि यह exec या शैल आउट है, लेकिन फ़ाइल हैंडल के विपरीत (जहां मैं उन्हें एन्कोडिंग के लिए बिनमोड कर सकता हूं) मुझे नहीं पता कि यह सुनिश्चित करने के लिए कि मैं क्या चाहता हूं। उस मामले के लिए system() के साथ ही। तो मेरा सवाल यह है कि मैं ठीक से ऊपर क्या नहीं कर रहा हूं? अन्यथा ओपनबीएसडी और सोलारिस पर पर्ल या खोल या पर्यावरण के साथ क्या अलग है?

[1] वास्तव में मुझे लगता है कि सीपीएएन परीक्षकों के नतीजों के अनुसार केवल लिनक्स ही है।

अद्यतन (x2): मैं वर्तमान में निम्नलिखित cpantester की व्यवस्था के माध्यम से अपनी तरह से चल रहा है Schwern की परिकल्पना का परीक्षण करने के लिए:

use strict; 
use warnings; 
use Data::Dumper; 

BEGIN { 
    if (@ARGV) { 
     require Test::More; 
     Test::More::diag("\npre utf8::all: " 
       . Dumper({ utf8 => $ARGV[0], bytes => $ARGV[1] })); 
    } 
} 

use utf8; 
use utf8::all; 

BEGIN { 
    if (@ARGV) { 
     Test::More::diag("\npost utf8::all: " 
       . Dumper({ utf8 => $ARGV[0], bytes => $ARGV[1] })); 
     exit; 
    } 
} 

use Encode; 
use Test::More; 

my $builder = Test::More->builder; 
binmode $builder->output,   ':encoding(UTF-8)'; 
binmode $builder->failure_output, ':encoding(UTF-8)'; 
binmode $builder->todo_output, ':encoding(UTF-8)'; 

my $utf8 = '¥'; 
my $bytes = encode_utf8($utf8); 

diag("\nPassing: " . Dumper({ utf8 => $utf8, bytes => $bytes, })); 

open(my $fh, '-|', $^X, $0, $utf8, $bytes) || die "open: $!"; 
my $result = join('', <$fh>); 
close $fh; 

ok(1); 
done_testing(); 

मैं विभिन्न प्रणालियों पर परिणाम पोस्ट करेंगे जब वे के माध्यम से आते हैं। इसकी वैधता और इसकी शुद्धता पर कोई भी टिप्पणी पकड़ी जाएगी। ध्यान दें कि यह मान्य परीक्षण होने का इरादा नहीं है। उपरोक्त का उद्देश्य विभिन्न प्रणालियों पर प्राप्त होने वाली तुलना की तुलना करने में सक्षम होना है।

संकल्प: वास्तविक अंतर्निहित मुद्दा मेरे प्रश्न में संबोधित नहीं किया गया है और न ही श्वेर्न के उत्तर से। मैंने जो खोजा वह यह है कि कुछ cpantesters मशीनों में केवल एक एसीआई लोकेल स्थापित/उपलब्ध है। मुझे इस प्रकार के पर्यावरण में काम करने के लिए कार्यक्रमों के लिए यूटीएफ -8 अक्षरों को पारित करने के किसी भी प्रयास की उम्मीद नहीं करनी चाहिए। तो अंत में मेरी समस्या अमान्य परीक्षण स्थितियां थी, अमान्य कोड नहीं।

मैंने यह इंगित करने के लिए अब तक कुछ भी नहीं देखा है कि qx ऑपरेटर या utf8::all मॉड्यूल का कोई बाहरी प्रभाव है कि बाहरी प्रोग्रामों को पैरामीटर कैसे पारित किए जाते हैं। बाहरी घटक को सूचित करने के लिए महत्वपूर्ण घटक LANG और/या LC_ALL पर्यावरण चर है, जो कि वे किस लोकेल में चल रहे हैं।

वैसे, मेरा मूल दावा है कि मेरा कोड उन सभी प्रणालियों पर काम कर रहा था जहां I18N :: Langinfo :: CODESET परिभाषित किया गया गलत था।

+0

संबंधित नोट पर, बीएसडी अन्य तरीकों से टूटा हुआ प्रतीत होता है। मैं फ्रीबीएसडी में एसएसएच सत्र के माध्यम से यूनिकोड वर्ण भी टाइप नहीं कर सकता - जिसके परिणामस्वरूप अजीब टर्मिनल व्यवहार होता है। –

+0

यूनिकोड-थ्रू-एसएसएच शायद उस टर्मिनल पर निर्भर करता है जिस पर आप टर्मिनल का उपयोग कर रहे हैं और आपका सिस्टम 'टीईआरएम' दोनों प्रणालियों पर क्या है। – sarnold

+0

मैं ओएस एक्स पर आपकी समस्या को दोहराना नहीं कर सकता, लेकिन आप यूनिकोड समेत अधिकांश यूनिकोड सुविधाओं को चालू करने के लिए [utf8 :: all] (https://metacpan.org/module/utf8::all) को आजमा सकते हैं '@ ARGV'। 'क्यूएक्स'' ओपन 'प्रगामा से भी प्रभावित हो सकता है, जो' utf8 :: all' फाइलों को यूनिकोड का सम्मान करने के लिए उपयोग करता है। – Schwern

उत्तर

1

qx खोल को कॉल करता है और यह दखल दे सकता है।

कि बचने के लिए, utf8::all उपयोग करने वाले सभी पर्ल यूनिकोड वूडू पर स्विच करने के लिए। फिर शैल से परहेज करते हुए अपने प्रोग्राम में पाइप खोलने के लिए open फ़ंक्शन का उपयोग करें।

use utf8::all; 
my $utf8 = '¥'; 

open my $read_from_script, "-|", "test_script", $utf8; 
print <$read_from_script>,"\n"; 
+0

खुले के 3-तर्क संस्करण के साथ खोल के उपयोग से बचने का एक अच्छा सुझाव है। हालांकि मैं नहीं देख सकता कि utf8 :: सभी को 'ओपन' फ़ंक्शन के तर्क और अंतर्निहित 'निष्पादन' कॉल पर तर्क होना चाहिए। –

+0

utf8 के स्रोत को देखकर :: यह वास्तव में '@ ARGV' के एन्कोडिंग के बारे में धारणा करता है [यह] (http://stackoverflow.com/questions/2037467/how-can-i-treat-command-line -र्गर-ए-यूटीएफ -8-इन-पर्ल) करने के खिलाफ चेतावनी दी। हालांकि यह इस सवाल से विषय बंद कर रहा है। –

+0

@ मार्क लॉरेंस 'utf8 :: all'' open' pragma के माध्यम से प्रभाव डाल रहा है। विशेष रूप से 'खुले उपयोग करें ": std" 'प्रभावशाली प्रतीत होता है पाइप खुलता है, शायद एसटीडीओयूटी यूटीएफ -8 का उपयोग करके। इसका एक अच्छा उदाहरण है "किसी और को इसे समझने दें और उनके मॉड्यूल का उपयोग करें"। और हां, यह '@ एआरजीवी' के एन्कोडिंग के बारे में एक धारणा बना रहा है। आपको एक धारणा बनाना है, भले ही आप एएससीआईआई नहीं मान रहे हैं, और यूटीएफ -8 एक बहुत ही सुरक्षित शर्त है। दुर्भाग्यवश यह ऐसा नहीं है जिसे व्याख्यात्मक रूप से किया जा सके। – Schwern