Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Rubys 유니코드 지원 테스트

Ruby 2.4와 함께 제공되는 새로운 기능 중에는 개선된 유니코드 지원이 있습니다. 특히 upcase와 같은 메소드 및 downcase 예상대로 작동하고 "ä"를 "Ä"로 바꾸고 다시 되돌립니다. 이것은 저를 궁금하게 만들었습니다. André Arko의 블로그 게시물을 읽은 2013년 이후로 어떤 다른 유니코드 개선이 이루어졌습니까? Ruby의 Strings는 이제 UTF-8입니다... 맞나요?

나는 Ruby의 모든 문자열 메소드를 테스트했는데, 기술적 오류가 아니라 "최소 놀라움의 원칙" 위반 여부를 찾습니다. 구체적으로 제 가정은 다음과 같았습니다.

  1. 고유한 문자: "e"와 "ë"가 다른 것처럼 "e"와 "E"가 다릅니다.
  2. 단일 문자는 단일 문자로 간주됩니다. 유니코드로 어떻게 표현되든 상관없습니다. 이는 "e"와 "ë"가 각각 단일 문자임을 의미하지만 후자는 두 개의 코드 포인트로 표시됩니다.
  3. 문자는 변경할 수 없습니다. 문자열을 반대로 해도 개별 문자가 변경되어서는 안 됩니다.
  4. 공백은 공백으로 처리됩니다. 까다로운 유니코드 공백 문자조차도.
  5. 숫자는 숫자로 취급됩니다. 숫자 2는 어떻게 쓰여지든 항상 숫자 2입니다.

불행히도 대부분의 Ruby 문자열 조작 방법은 이러한 테스트에 실패합니다. 유니코드 문자열로 작업하는 경우 어떤 문자열을 사용할지 매우 주의해야 합니다.

<블록 인용>

참고:출판 후 일부 독자는 내가 언급한 많은 실패가 유니코드 테스트 문자열을 정규화했다면 발생하지 않았을 것이라고 지적했습니다. 이것은 사실입니다. 그러나 문자열은 Ruby 또는 Rails(내가 테스트한 모든 앱에서)에 의해 자동으로 정규화되지 않습니다. 이 테스트는 항상 최악의 경우를 설명하기 위한 것이며 그런 점에서 여전히 유용하다고 생각합니다.

Ruby 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 ["ä"] ["a", "̈"] 조심하세요!
#chomp "ä ".chomp "ä" "ä" 알았어
#찹 "ä".chop "" "a" 조심하세요!
#chr "ä".chr "ä" "a" 조심하세요!
#클리어 "ä".clear "" "" 알았어
#코드포인트 "ä".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 "\"a\\u0308\"" "\"a\\u0308\"" 알았어
#각_바이트 "ä".each_byte.to_a [97, 204, 136] [97, 204, 136] 알았어
#각_문자 "ä".each_char.to_a ["ä"] ["a", "̈"] 조심하세요!
#각_코드포인트 "ä".each_codepoint.to_a [97, 776] [97, 776] 알았어
#각 줄 "ä".each_line.to_a ["ä"] ["ä"] 알았어
#비어 있습니까? "ä".empty? false false 알았어
#encode "ä".encode("ASCII", undef: :replace) "a?" "a?" 알았어
#인코딩 "ä".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("a") nil 0 조심하세요!
#교체 "ä".replace("u") "u" "u" 알았어
#삽입 "ä".insert(1, "u") "äu" "äu" 조심하세요!
#검사 "ä".inspect "\"ä\"" "\"ä\"" 알았어
#인턴 "ä".intern :ä :ä 알았어
#길이 "ä".length 1 2 조심하세요!
#그냥 "ä".ljust(3, "_") "ä__" "ä_" 조심하세요!
#lstrip " ä".lstrip "ä" "ä" 알았어
#매치 "ä".match("a") nil # 조심하세요!
#다음 "ä".next "ä" "b̈" 조심하세요!
# 또는 "ä".ord 97 97 알았어
#파티션 "händ".partition("a") ["händ"] ["h", "a", "̈nd"] 조심하세요!
#앞에 추가 "ä".prepend("ä") "ää" "ää" 알았어
#교체 "ä".replace("ẍ") "ẍ" "ẍ" 알았어
#역방향 "händ".reverse "dnäh" "dn̈ah" 조심하세요!
#r파티션 "händ".rpartition("a") ["händ"] ["h", "a", "̈nd"] 조심하세요!
#rstrip "line ".rstrip "line" "line " 조심하세요!
#스크럽 "ä".scrub "ä" "ä" 알았어
#setbyte s = "ä"; s.setbyte(0, "x".ord); s "ẍ" "ẍ" 알았어
#크기 "ä".size 1 2 조심하세요!
#슬라이스 "ä".slice(0) "ä" "a" 조심하세요!
#분할 "ä".split("a") ["ä"] ["", "̈"] 조심하세요!
#스퀴즈 "ää".squeeze("ä") "ä" "ää" 조심하세요!
#start_with? "ä".start_with?("a") false true 조심하세요!
#스트립 " line ".strip "line" " line " 조심하세요!
#sub "ä".sub("a", "x") "ä" "ẍ" 조심하세요!
#성공 "ä".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("c̈").to_a ["ä", "b̈", "c̈"] ["ä", "b̈", "c̈"] 알았어
#valid_encoding? "ä".valid_encoding? true true 알았어