1, 【募集】 これまでにRuby on Rails チュートリアル第2版の監修および半分程度を翻訳、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れて更新翻訳中。 ruby -Ku」を指定しておきます。, そしてプログラムを保存する時は文字コードをUTF-8に指定して保存します。, 通常はこれでいいのですが、Windowsで標準出力としてコマンドプロンプトを使用している場合、コマンドプロンプトの文字コードがShift_JISのためそのまま「print」メソッドなどで出力すると文字化けします。, よって標準出力へ出力する場合は、UTF-8からShift_JISへ文字コード変換してから出力する必要があります。文字コード変換する方法はいくつかあるのですが今回は「Kconv」モジュールを使用します。, 「Kconv」モジュールの詳しい解説は別のページで行います。ここでは使い方だけ見てください。まず「require」メソッドで「kconv」ライブラリを読み込みます。そしてモジュール関数として用意されている「Kconv.tosjis(str)」を使って文字コードをShift_JISに変換します。実際にプログラムする場合は次のようになります。, 文字コードをUTF-8で保存する場合、BOM(バイトオーダーマーク)付きにすると問題が発生します。UTF-8で保存する場合はBOM無しにして下さい。, 下記は先ほど無事に動いたプログラムですが、保存する時にUTF-8のBOM付きで保存してみます。, このようにエラーが発生します。, エラーを見て頂くと分かる通り1行目でエラーが発生していることになっています。UTF-8でBOMを付けた場合にはプログラムの先頭に3つのバイト「EF BB BF」が付きます。「EF BB BF」をそれぞれ8進数にした値が「357 273 277」です。Rubyはこの3つの文字を不正な値としてエラーにしているわけです。, UTF-8で保存する場合にはBOM無しで保存して下さい。, 初心者~中級者の方を対象としたプログラミング方法や開発環境の構築の解説を行うサイトの運営を行っています。. 0, 回答 . 文字列のエンコーディング情報を表現した Encoding オブジェクトを返します。 Ruby 2.7.0 リファレンスマニュアル ライブラリ一覧 コンピュータ上ではバイナリ形式(2進数)で表されるため、 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 Windows環境であっても文字コードはUTF-8ベースが主流となってきていることもあり、今後のRubyサンプルも文字コードにUTF-8を使っていきます。そこでWindows環境でUTF-8を使ってプログラミングを行うまとめをしておきます。, まずUTF-8を使用しますのでプログラムの先頭行に「#! 2 / クリップ いきなりの展開にくらくらきましたが、babaさんはさらにたたみかけます。, こうしたことはとっくにご存じの方も多いと思いますが、「Rubyといえば2.0以来UTF-8完全対応なんじゃないの」と勝手に思い込んでた私は脳に掌底を食らったような思いです。ああ、でもこういうことがあるから面白い。, まず最初に押さえておきたい点です。プログラミング言語で文字コードに関連する部分は、「文字列」「正規表現」「入出力」「コード中の文字リテラル(””の中など)」「コード中の文字リテラル以外の要素(変数名など)」「ファイル名」などが中心になります。そして文字列に関連して「ソート順」などについても考慮が必要です。, とbabaさんが指摘しているとおり、Rubyで文字コードに関連するのはほとんどの場合標準ライブラリです。, Java、C#、Python、Perl、Goなど、多くの言語では内部でUnicodeを用いています。言い方を変えれば、文字コードを固定してそれ以外のコードについては変換のみで対応するということです。このように内部表現をUnicodeの文字コードに統一する方式をUCS正規化(UCS Normalization)と呼びます【注: リンク修正いたしました】。UCSは「UnicodeUniversal Character Set」の略です。, UCS正規化を採用している言語では、たとえばStringクラスなどで原則としてその文字コードしか保存できません。たとえばJavaのStringクラス、Characterクラス、char型であれば文字をUTF-16で保存します。そのため、UTF-16Unicodeに含まれない文字(実はそれなりにあるのです)は原則として言語標準のStringクラスなどでは扱わない/扱えないことになります。, こうした言語でも、標準のStringクラスなどを使わずにchar[]型などに保存して自力でハンドリングしたり別ライブラリで扱ったりする分には構いませんし、その必要が生じることはいくらでもありえます。, これに対し、Rubyは1.9でCSI(Code Set Independent)という独自の多言語化方式を導入しました。, UCS正規化と異なり、CSI方式では特定の内部コードを仮定しません。たとえばStringクラスの変数にはその気になればUnicode以外の文字コードでも直接保存できます。つまり文字列は内部的に事実上バイナリとして保存されているのです。その代わりStringクラスで文字コード情報を持てるようにする(以下のコード例の#encoding)などの改良が行われました。, 実装が複雑になることもあり、CSI方式を導入した言語はRuby以外にはなかなかないようですが、多様性に富んだチャレンジングな多言語化方式とされています。なお、Ruby 1.9でオレオレ文字コードを導入してみた豪の者を見つけました。, また、1.9ではマジックコメントが導入され、スクリプトファイルの冒頭(冒頭がshebangの場合は2行目)に# coding: euc-jpなどの方法でファイルのエンコーディングを指定できるようになりました。, ただし1.9の場合、マジックコメントを指定しない場合のデフォルトのファイルエンコーディングはUS-ASCIIです。UTF-8ではありません。, Rubyが2.0になってから、このマジックコメントを指定しない場合のデフォルトのファイルエンコーディングがUS-ASCIIからUTF-8に変更されました。, 2.0でのデフォルト文字コードの変更はもちろん大きなものであり、他にも文字コードについての変更点はありますが、CSIの部分に関しては引き続き変わっていません。つまり2.0の文字列は1.9のときと同様、内部では事実上バイナリなのです。, Rubyでは、1.9でのCSI導入、2.0でのデフォルトのファイルエンコーディングのUTF-8への変更という段階的な方法で多言語化を切り替えてきました。2.0以降、これらの点について変更はありません。, 私がRuby 2.0からUTF-8完全対応だと思い込んでいたのはいろんな意味で誤りでした。後述するようにRubyは1.9より前からUTF-8を含む複数の文字コードを扱えましたし、2.0でUTF-8になったのはデフォルトのファイルエンコーディングです。, Ruby 1.8以前は文字列をデフォルトでASCII単位でとして扱い、文字列メソッドもバイト単位で動作しました。たとえば1.8でstr="ab漢字"の後でstr[2]の値を取り出すと0xB4(EUCの「漢」の最初のバイト)になりました。, 1.8以前でこうしたスクリプトを実行するには、スクリプトファイルの文字コードに応じた-Ku(UTF-8)や-Ke(EUC-JP)や-Ks(Shift_JIS)などのオプション指定が欠かせませんでした(2.0から非推奨)。指定したオプションは$KCODEで確認でき、正規表現は$KCODEに応じて文字数の数え方が変わりました。文字列ごとに異なる文字コードを指定することはできませんでした($KCODEは1.9で廃止)。, UCS正規化とCSIには、それぞれメリットとデメリットがあります。どちらが優れているというものではなく、ユースケースによって変わります。, 一般にUCS正規化では文字コードの実装を一本化できますが、Unicodeにない文字などは標準的な方法では直接扱えないので別のライブラリなどで対応する必要があります。, CSIでは標準的な方法で複数の文字コードを同時に扱うことができますが、正規表現の文字数の数え方などを文字コードに応じて実装側で切り替えるなど、実装が複雑になることが考えられます。, 今回の記事では『プログラマーのための文字コード技術入門』に大変お世話になりました。, 同書の裏帯に書かれているように、特定の文字コード体系を押したりせず、評価を読者の判断に任せている点に好感が持てます。同書ではRuby 1.8と当時最新だったRuby 1.9を比較しており、決して新しい内容ではありませんが、今回取り上げたRuby 1.9でのCSI導入についても詳しく解説されていて、現在でも読む価値のある良書です。Unicode、UTF-8が万能ではないということがわかったのは自分にとっては大きな収穫でした。, 文字コードはどこまで行っても奥が深いので、理解の甘いところがありましたらTwitterで私までお知らせいただけると幸いです。, RubyでCSI正規化が採用された経緯についてMatz自らQuoraで回答していました。, MySQLのencodingをutf8からutfmb4に変更して寿司ビール問題に対応する, Twitter: @hachi8833、GitHub: @hachi8833 0, 回答 こんにちは、hachi8833です。 少し前に、babaさんから「Rubyの内部文字コードはUTF-8じゃないよ」とツッコミがありました。 (追記: 上は会話の途中から切り取りましたのでご了承ください) いきなりの展開にくらくらきましたが、babaさんはさらにたたみかけます。 こうしたことはとっく … ワンライナーでも使えるし、オブジェクト指向を使った本格的なシステムも組める。何より、"Enjoy programming"という設計思想で作られていて、プログラムを組んでいてストレスを感じることが少ない。 "\a"は、7という値を持つ1バイトのRuby文字列表現。, また下記の[82, 117, 98, 121]をpackすると"Ruby"という文字になりますが、この[82, 117, 98, 121]は何の数字なのでしょうか。, それぞれ、R u b yの文字コードです。 teratailを一緒に作りたいエンジニア, ご回答ありがとうございます。「バイナリ」「文字コード」などのキーワードを中心に、コンピュータの基礎的な部分から学習しなおしてみます。, 数値10は制御文字としてはLF(改行)で、16進数表記だと\x0Aで、(エスケープシーケンス+文字)表記だと\n, というより、何のためにpack/unpackを使うのかが気になります(Rubyだけでも、コードゴルフのような特殊な場面で使うこともなくはないですが)。, ご回答ありがとうございます。調べなおしたところ、確かに変換される値はASCII文字でした。, http://digital.ni.com/public.nsf/allkb/D831B5F2D5CA212E86257A21002055E6, 例えばrubyで下記のコードを実行した結果、下記の通りになったのですが変換後の値("\x01"や"\a")はどこから出てきたのでしょうか。ASCIIコードではないですよね。。, unpackは「バイナリ(と文字列)を数値に変換する関数」という認識ですが、なんの数値に変換されるのでしょうか。, そもそもの前提知識が足りないために理解できないのですが、どういったキーワードで知識を仕入れたらよいでしょうか。 例)「文字コード」「バイナリとは」など。。. 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。, マジックコメントを指定しない場合のデフォルトのファイルエンコーディングがUS-ASCIIからUTF-8に変更されました, RubyではなぜUCS正規化を採用していないのでしょうか?に対するYukihiro Matsumotoさんの回答 - Quora. 1 / クリップ "\a"は、7という値を持つ1バイトのRuby文字列表現。 また下記の[82, 117, 98, 121]をpackすると"Ruby"という文字になりますが、この[82, 117, 98, 121]は何の数字なのでしょうか。 それぞれ、R u b yの文字コードです。 文字と文字コードは、ord chrで変換できます。 Let'sプログラミング ©2006-2020 Buzzword Inc.. All Rights Reserved. Windows環境であっても文字コードはUTF-8ベースが主流となってきていることもあり、今後のRubyサンプルも文字コードにUTF-8を使っていきます。そこでWindows環境でUTF-8を使ってプログラミングを行うまとめをしておきます。 Subject: [ruby-list:34454] Re: 文字コード混在スクリプトの実行 From: nobu.nakada@ f . プログラム上でそういったバイナリファイルを扱う際にpackを使うのかなー、といった程度の理解だったのですが、 1 / クリップ 2 / クリップ お世話になります。 たけ(tk)です。 [ruby-list:34450] Re: 文字コード混在スクリプトの実行 にて nobu.nakada / nifty.ne.jp さん 曰く: 》 > 文字コード混在のスクリプトを実行したいのですが、 》 > どういう方法があるでしょうか? 》 > (-K?