たけ(tk)です。

[ruby-list:34454] Re: 文字コード混在スクリプトの実行 にて 
nobu.nakada / nifty.ne.jp さん 曰く:
》そうです。だから、あまり現実的な方法ではありませんが、requireの前に$KCODEを設定してやれば、正しくパースできます。

ということは、中村さんの場合に

3) EUC, SJIS 混在
   body.rb  EUC  (for UNIX and Win)
   ui_1.rb  EUC  (for UNIX)
   ui_2.rb  SJIS (for Win)

で次のようにすればうまくいくということでしょうか?。

-- body.rb
old_kcode = $KCODE
if Unix
  $KOCDE = "e"
  require "ui_1"
else
  $KCODE = "s"
  require "ui_2"
end
$KCODE = old_kcode

正しくパースはできる(パース時のエラーで落ちることはない)が、実行時に処
理系が想定している $KOCDE とデータとして入っている文字列のコードとが異な
るので、実行時におかしくなる。ということでは?。

》> (B)ただし、トップレベルのスクリプトの場合には、$KCODE も変更する。> (というか、$KOCDE=="n" の時には -Ks で変更する)。
》
》この"n"の時には、ってのがちょっと意味がよく分からなかったんですが、DEFAULT_KCODEがNONEじゃないときには-Kで変更しないということ?

 次のように変更します。

 (B)ただし、トップレベルのスクリプトの場合には、$KCODE も変更する。
require で呼び出されたスクリプトでは、$KOCDE=="n" の時にだけ -Ks で変更
する。

 $KCODE 決定の順位は次のようになります。(たけ(tk)案、念のため)。

(1)コマンドラインオプション/トップレベルスクリプトの -Kx
(2)ruby.so のデフォルト
(3)require されたスクリプトで最初に -Ks を有するものの指定。

》> (D)require で呼ばれたスクリプトの記述コード(-Ks)と require が実行され> た時点での記述コード($KCODE)とが異なる場合には、(4)のパースの時に文字> コードの変換(-Ks → $KCODE)を行う。
》
》これはちょっと疑問です。必要なのであれば変換を明示したほうがいいのではないかと思ってます。

 sjis のスクリプトでパース時に変数に保存された文字列(sjis)を実行時の
エンコーディング(EUC)で処理しても問題がなければ、変換は必要ではない、
ですけど・・。

》そもそも、requireが実行された時点でのエンコーディングに変換してしまっていいのでしょうか。a.rb->b.rb->c.rbとrequireされる場合、c.rbのリテラルはb.rbのエンコーディングに合わせるべきなのでしょうか。

 b.rb のエンコーディングではなく $KCODE(a.rb の -Ks)に合わさるはず。

 トップレベルの a.rb で -Ks が指定されていない場合には、b.rb(最初に見
つかった -Ks 指定のあるスクリプト)のエンコーディングに従うことになる。
a.rb で指定されていないということは、日本語を使っていない、または、どの
エンコーディングにでも対応できる、ということなので、最初に見つかった -Ks 
を $KCODE として、実行時の標準としても構わないと思う。

》ソースのエンコーディング自体を変更したときに修正するのが面倒だということであれば、コンパイル時に決定される疑似変数(__CODING__とか)を導入するということも考えられます。

 ??、ruby.so をコンパイルする話?。

》> (E)require を実行よりまえにそのファイル全体の文字列解釈が終了している> のであれば、-Ks のデータを保存しておく必要はない。
》
》このデータというのは、そのファイルの先頭で指定されたエンコーディングのことですか?

 はい。

》> (F)もし、require から返ってきた後に文字列の解釈が必要になるのであれば、> require するときに(3)、そのファイルの記述コード(-Ks)を保存しておき、> require から戻ってきたときには(6)、元の記述コードの戻して文字列の解釈> (パース?/実行?)を継続する。
》
》requireすると$KCODEが自動的に変わってしまうというのはまずいと思うので、(3)、(4)の前後ではエンコーディングは保存されるべきだと思います。ただし、(5)の実行中の変更は(6)でも有効になるべきではないでしょうか。

 $KCODE は最初に見つかった -Ks にだけ影響を受けるので、トップレベルのス
クリプトで指定されていれば、require で $KCODE は変わらない。という前提。

 この項目は「もし、require から返ってきた後に文字列の解釈が必要になるの
であれば」という前提が間違っているので、余分でした。

Take_tk = KUMAGAI Hidetake
たけ(tk)=熊谷秀武