रूबी 2.4 के साथ शिप की गई नई सुविधाओं में बेहतर यूनिकोड समर्थन है। विशेष रूप से, upcase
. जैसी विधियां और downcase
उम्मीद के मुताबिक काम करें, "ä" को "Ä" और पीछे की ओर मोड़ें। इसने मुझे उत्सुक बना दिया:2013 के बाद से अन्य यूनिकोड सुधार क्या किए गए हैं जब मैंने आंद्रे आर्को के ब्लॉग पोस्ट स्ट्रिंग्स इन रूबी यूटीएफ -8 को पढ़ा है ... ठीक है ??
मैंने रूबी की सभी स्ट्रिंग विधियों का परीक्षण किया, तकनीकी त्रुटियों की तलाश में नहीं बल्कि "कम से कम आश्चर्य के सिद्धांत" के उल्लंघन के लिए। विशेष रूप से, मेरी धारणा यह थी कि:
- अद्वितीय वर्ण अद्वितीय होते हैं: "ई" और "ë" अलग हैं, जैसे "ई" और "ई" हैं।
- एकल वर्ण एकल वर्णों के रूप में गिने जाते हैं, कोई फर्क नहीं पड़ता कि वे यूनिकोड में कैसे प्रदर्शित होते हैं। इसका मतलब है कि "ई" और "ë" प्रत्येक एक एकल वर्ण हैं, भले ही बाद वाले को दो कोड बिंदुओं द्वारा दर्शाया गया हो।
- अक्षर अपरिवर्तनीय होते हैं। वर्णों की एक स्ट्रिंग को उलटने से अलग-अलग वर्णों में परिवर्तन नहीं होना चाहिए।
- व्हाइटस्पेस को व्हाइटस्पेस माना जाता है। यहां तक कि उन मुश्किल यूनिकोड व्हाइटस्पेस वर्ण भी।
- अंकों को अंक माना जाता है। नंबर 2 हमेशा नंबर 2 होता है चाहे वह कैसे भी लिखा हो।
दुर्भाग्य से, रूबी की अधिकांश स्ट्रिंग हेरफेर विधियां इन परीक्षणों में विफल हो जाती हैं। यदि आप यूनिकोड स्ट्रिंग्स के साथ काम कर रहे हैं, तो आपको बेहद सावधान रहना होगा कि आप किसका उपयोग करते हैं।
<ब्लॉकक्वॉट>नोट:प्रकाशन के बाद, कुछ पाठकों ने बताया कि मैंने जिन विफलताओं का उल्लेख किया है उनमें से कई ऐसी नहीं होतीं अगर मैं यूनिकोड टेस्ट स्ट्रिंग्स को सामान्य कर देता। यह सच है। हालाँकि, रूबी या रेल्स (मेरे द्वारा परीक्षण किए गए किसी भी ऐप में) द्वारा स्ट्रिंग्स को स्वचालित रूप से सामान्य नहीं किया जाता है। ये परीक्षण हमेशा सबसे खराब स्थिति का वर्णन करने के लिए थे और मुझे लगता है कि वे उस संबंध में अभी भी उपयोगी हैं।
रूबी 2.4.0 के साथ यूनिकोड परीक्षण
विधि | <थ>परीक्षाअपेक्षित | <थ>परिणामफैसला | ||
---|---|---|---|---|
#% | "%s" % "noël" | "noël" | "noël" | ठीक है |
#* | "noël" * 2 | "noëlnoël" | "noëlnoël" | ठीक है |
#<< | "noël" << "ë" | "noëlë" | "noëlë" | ठीक है |
#<=> | "ä" <=> "z" | -1 | -1 | ठीक है |
#== | "ä" == "ä" | true | true | ठीक है |
#=~ | "ä" =~ /a./ | nil | 0 | सावधान! |
#[] | "ä"[0] | "ä" | "a" | सावधान! |
#[]= | "ä"[0] = "u" | "u" | "u" | ठीक है |
#b | "ä".b.encoding.to_s | "ASCII-8BIT" | "ASCII-8BIT" | ठीक है |
#बाइट्स | "ä".bytes | [97, 204, 136] | [97, 204, 136] | ठीक है |
#bytesize | "ä".bytesize | 3 | 3 | ठीक है |
#byteslice | "ä".byteslice(1) | "\xCC" | "\xCC" | ठीक है |
#पूंजीकरण | "ä".capitalize | "Ä" | "Ä" | ठीक है |
#casecmp | "äa".casecmp("äz") | -1 | -1 | ठीक है |
#केंद्र | "ä".center(3) | " ä " | "ä " | सावधान! |
#chars | "ä".chars | ["ä"] | ["a", "̈"] | सावधान! |
#chomp | "ä
".chomp | "ä" | "ä" | ठीक है |
#चॉप | "ä".chop | "" | "a" | सावधान! |
#chr | "ä".chr | "ä" | "a" | सावधान! |
#स्पष्ट | "ä".clear | "" | "" | ठीक है |
#codepoints | "ä".codepoints | [97, 776] | [97, 776] | ठीक है |
#concat | "ä".concat("x") | "äx" | "äx" | ठीक है |
#गिनती | "ä".count("a") | 0 | 1 | सावधान! |
#क्रिप्ट | "123".crypt("ää") == "123".crypt("aa") | false | false | ठीक है |
#हटाएं | "ä".delete("a") | "ä" | "̈" | सावधान! |
#डाउनकेस | "Ä".downcase | "ä" | "ä" | ठीक है |
#dump | "ä".dump | "\"a\\u0308\"" | "\"a\\u0308\"" | ठीक है |
#each_byte | "ä".each_byte.to_a | [97, 204, 136] | [97, 204, 136] | ठीक है |
#each_char | "ä".each_char.to_a | ["ä"] | ["a", "̈"] | सावधान! |
#each_codepoint | "ä".each_codepoint.to_a | [97, 776] | [97, 776] | ठीक है |
#each_line | "ä".each_line.to_a | ["ä"] | ["ä"] | ठीक है |
#खाली? | "ä".empty? | false | false | ठीक है |
#encode | "ä".encode("ASCII", undef: :replace) | "a?" | "a?" | ठीक है |
#encoding | "ä".encoding.to_s | "UTF-8" | "UTF-8" | ठीक है |
#end_with? | "ä".end_with?("ä") | true | true | ठीक है |
#eql? | "ä".eql?("a") | false | false | ठीक है |
#force_encoding | "ä".force_encoding("ASCII") | "a\xCC\x88" | "a\xCC\x88" | ठीक है |
#getbyte | "ä".getbyte(2) | 136 | 136 | ठीक है |
#gsub | "ä".gsub("a", "x") | "ä" | "ẍ" | सावधान! |
#हैश | "ä".hash == "a".hash | false | false | ठीक है |
#शामिल हैं? | "ä".include?("a") | false | true | सावधान! |
#index | "ä".index("a") | nil | 0 | सावधान! |
#बदलें | "ä".replace("u") | "u" | "u" | ठीक है |
#सम्मिलित करें | "ä".insert(1, "u") | "äu" | "aü" | सावधान! |
#निरीक्षण | "ä".inspect | "\"ä\"" | "\"ä\"" | ठीक है |
#इंटर्न | "ä".intern | :ä | :ä | ठीक है |
#लंबाई | "ä".length | 1 | 2 | सावधान! |
#समायोजित | "ä".ljust(3, "_") | "ä__" | "ä_" | सावधान! |
#lstrip | " ä".lstrip | "ä" | "ä" | ठीक है |
#मिलान | "ä".match("a") | nil | # | सावधान! |
#अगला | "ä".next | "ä" | "b̈" | सावधान! |
#ord | "ä".ord | 97 | 97 | ठीक है |
#विभाजन | "händ".partition("a") | ["händ"] | ["h", "a", "̈nd"] | सावधान! |
#preपेंड | "ä".prepend("ä") | "ää" | "ää" | ठीक है |
#बदलें | "ä".replace("ẍ") | "ẍ" | "ẍ" | ठीक है |
#रिवर्स | "händ".reverse | "dnäh" | "dn̈ah" | सावधान! |
#rpartition | "händ".rpartition("a") | ["händ"] | ["h", "a", "̈nd"] | सावधान! |
#rstrip | "line ".rstrip | "line" | "line " | सावधान! |
#स्क्रब | "ä".scrub | "ä" | "ä" | ठीक है |
#सेटबाइट | s = "ä"; s.setbyte(0, "x".ord); s | "ẍ" | "ẍ" | ठीक है |
#आकार | "ä".size | 1 | 2 | सावधान! |
#टुकड़ा | "ä".slice(0) | "ä" | "a" | सावधान! |
#विभाजन | "ä".split("a") | ["ä"] | ["", "̈"] | सावधान! |
#निचोड़ | "ää".squeeze("ä") | "ä" | "ää" | सावधान! |
#start_with? | "ä".start_with?("a") | false | true | सावधान! |
#strip | " line ".strip | "line" | " line " | सावधान! |
#sub | "ä".sub("a", "x") | "ä" | "ẍ" | सावधान! |
#succ | "ä".succ | "b̈" | "b̈" | ठीक है |
#स्वैपकेस | "ä".swapcase | "Ä" | "Ä" | ठीक है |
#to_c | "١".to_c | (1+0i) | (0+0i) | सावधान! |
#to_f | "١".to_f | 1.0 | 0.0 | सावधान! |
#to_i | "١".to_i | 1 | 0 | सावधान! |
#to_r | "١".to_r | (1/1) | (0/1) | सावधान! |
#to_sym | "ä".to_sym | :ä | :ä | ठीक है |
#tr | "ä".tr("a", "b") | "ä" | "b̈" | सावधान! |
#अनपैक करें | "ä".unpack("CCC") | [97, 204, 136] | [97, 204, 136] | ठीक है |
#upto | "ä".upto("c̈").to_a | ["ä", "b̈", "c̈"] | ["ä", "b̈", "c̈"] | ठीक है |
#valid_encoding? | "ä".valid_encoding? | true | true | ठीक है |