String#mb_charsとis_utf8?|TechRacho(テックラッチョ)〜エンジニアの「?」を「!」に〜|BPS株式会社エンジニアの「?」を「!」に。String#mb_charsとis_utf8?hachi8833シェアツイートブックマークLINEこんにちは、hachi8833です。ActiveSupport探訪シリーズ、今回はかわいらしいIntegerクラスに続いてStringのマルチバイト系メソッドにお邪魔します。Supportですが、今回はどうでしょうか。2.4.0active_support/core_ext/string/multibyte.rbmultibyte.rbのコードはこれまた簡素です。endendString#mb_chars文字列系メソッド用のマルチバイトセーフなプロキシString#is_utf8?UTF-8かどうかを論理値で返すString#mb_charsの方はこれだけでは不足なので、コメントをざっと訳してみます。String#mb_charsのコメント訳マルチバイトプロキシString#mb_charsは、文字列系メソッドで使えるマルチバイトセーフなプロキシです。以下単にCharsクラス)を返します。このクラスには元の文字列がカプセル化されて保存されます。Stringクラスのメソッドのうち、Unicodeに対応しているものはすべてこのプロキシクラス上で定義されます。Stringクラスの特定のメソッドがこのプロキシクラスに応答しない場合、カプセル化された文字列にメソッドが転送されます。“lj”はlとjの合字、“LJ”はLとJの合字です。メソッドチェーンCharsプロキシ上の、通常なら文字列を返すすべてのメソッドはCharsオブジェクトを返すようになります。これにより、それらのどのメソッドから返った結果もほかのメソッドにチェインできるようになります。12相互変換と設定このCharsオブジェクトは、できる限りStringオブジェクトと相互変換可能になっています。これにより、StringとCharsの間でのソートや比較が期待どおり動作します。!のついた破壊的メソッドを使うと、内部の文字列表現はCharsオブジェクトに変換されます。相互変換の問題は#to_sを呼び出すことで簡単に解決できます。Charsプロキシに定義されているメソッドについて、詳しくはActiveSupport::Multibyte::Charsをご覧ください。デフォルトのMultibyteクラスの動作を変更する方法については、ActiveSupport::Multibyteをご覧ください。String#mb_charsを動かしてみるというわけで、コードは簡潔でもやはり読み取りは一筋縄ではいきませんでした。2.4で"lj".upcaseを実行してみると、あれ?#mb_charsしなくても大文字に変換できました。少なくともString#upcaseはマルチバイトに対応しています。multibyte.rbの履歴を見てみると、2015年から特に動きがありません。1.9での対応がそもそものきっかけだったようです。2.4での非ASCII文字の大文字小文字変換の拡張です。2.3(Railsは5.0.1)でもう一度やってみると、今度は上のサンプルのとおり#mb_charsを介することで大文字に変換できました。2.4を使っていれば#mb_charsなしでUnicode仕様に沿った大文字小文字変換に対応できます。String#capitalizeString#downcaseString#upcaseString#swapcaseその他の#decomposeといったメソッドをマルチバイトセーフに扱うには、ActiveSupport::Multibyte::Charsに記載されているように#mb_charsを介して使います。2.4ではまだUnicode仕様に対応していない([A-Za-z]のみ対応)とのことなので、ActiveSupportのActiveSupport::Multibyte::Unicode#normalizeで正規化する必要があります。0String#mb_charsだけでは#casecmpに対応できません。0ActiveSupport::Multibyte::Charsクラスについて追いきれなかったので、次回再挑戦いたします。追伸つい先ごろ「「ユニコード」で予期せぬ目に遭った話」という記事が話題になりました。String#mb_charsからは外れますが、同記事で言及されていた以下の文字について私も少しだけ確認してみました。U+2EC4)2つの文字はほぼそっくりですが、前者は普通の文字、後者は漢字の「部首」であり、意味論(semantics)的に異なるものとして扱われます。この2つの文字は現在のUnicodeの定義上#normalizeで均すことができませんし、同じに扱われてはいけない文字です。"\"\\u2EC4\""現実にこうした部首文字が混入してしまった場合のことを考えると、なかなか頭の痛い問題です。コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。チュートリアル第2版の監修および半分程度を翻訳、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れて更新翻訳中。enno.jpを運営。実は最近Go言語が好きで、Goで書かれたRubyライクなGoby言語のメンテナーでもある。仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。Storageを使ってはいけない(翻訳)#Tags#会社紹介#自社サービス#勉強会#Rails#PHP#デザイン#実績#週刊RailsウオッチCONTACTお気軽にご相談ください。(翻訳)CONTACTTechRachoでは、パートナーシップをご検討いただける方からのご連絡をお待ちしております。お気軽にご意見・ご相談ください。