経過分秒表示(続)
前に同じような事もあった(time.rb 経過分秒表示 - Rubyとか Illustratorとか SFとか折紙とか)のだが、やはりライトニングトーク絡みで時間表示を作ってみた(申し込んだLT自体は reject)。取敢えずソース
LT_timer.rb (このソースはその後更新されています、11/1/2)
#coding:Windows-31J # $Id: LT_timer.rb 3582 2010-07-04 09:32:14Z hs9587 $ # $Date: 2010-07-04 18:32:14 +0900 (譌・, 04 7 2010) $ # $Name$ $Author: hs9587 $ $Revision: 3582 $ Version = "0.0 ($Revision: 3582 $)" require 'vr/vruby' require 'vr/vrcontrol' require 'vr/vrtimer' require 'vr/vrlayout' require 'time' Min = Time.parse('00:01')-Time.parse('00:00') class TimerControl < VRPanel include VRTimerFeasible include VRDrawable SrartResetStruct= Struct.new :name, :button, :body StartReset = [ SrartResetStruct.new('start', '!' \ , lambda{@start_time = Time.now; def anchor_time; @start_time; end}), SrartResetStruct.new('reset', '0' \ , lambda{def anchor_time; Time.now; end}), SrartResetStruct.new('exit', '.', lambda{exit}), ] attr_writer :time_out, :time_color def construct self.caption = 'LTTimer' #addTimer 1000 addTimer 50 @font = @screen.factory.newfont 'MS ゴシック', -72 #@font = @screen.factory.newfont 'HG ゴシックE', -72 #@font = @screen.factory.newfont 'HGS ゴシックE', -72 #@font = @screen.factory.newfont 'Tahoma', -72, 400, 0, 0, 0, 34, 0 #@font = @screen.factory.newfont 'Tahoma', -72 @time_out = 5.0 @time_color = 3.0 end # def construct def self_paint elapse = Time.at((Time.now - anchor_time).abs) self.textColor = RGB elapsed(elapse), 0, 0 mm_ss = elapse.strftime '%M:%S' setFont @font #p textExtent(mm_ss) drawText mm_ss, 0,0, *textExtent(mm_ss) end # def self_paint def self_timer refresh end StartReset.each do |start_reset| define_method start_reset.name, start_reset.body end # StartReset.each do |start_reset| private def anchor_time Time.now end # def anchor_time def elapsed(sec) sec = sec.to_i case sec when 0 ... Min*@time_color then 0 when Min*@time_color ... Min*@time_out then 256 * (sec - Min*@time_color) / (Min*(@time_out - @time_color)) else sec < 0 ? 0 : 255 end # case sec end # def elapsed(sec) end # class TimerControl < VRPanel class StartResetControl < VRPanel include VRVertLayoutManager include VRStdControlContainer def construct TimerControl::StartReset.each do |start_reset| addControl VRButton, start_reset.name, start_reset.button send_parent start_reset.name, 'clicked' end # TimerControl::StartReset.each do |start_reset| end # def construct end # class StartResetControl < VRPanel module LTTimer attr_reader :timer def construct self.caption = 'LTTimer' move 0,0, 198,104 addControl TimerControl, 'timer', 'Timer', 0,0, 180,72 addControl StartResetControl, 'buttons', 'Buttons', 181,0, 10,72 top 0xffffffff end # def construct TimerControl::StartReset.each do |start_reset| define_method("buttons_#{start_reset.name}_clicked") do @timer.send start_reset.name end # define_method("buttons_#{start_reset.name}_clicked") do end # TimerControl::StartReset.each do |start_reset| end # module LTTimer time_out, time_color, start = 5, 3, false require 'optparse' ARGV.options do |opt| opt.on('-o', '--timeout=VAL', 'default: 5(min)'){|v| time_out = v.to_f} opt.on('-c', '--timecolor=VAL', 'default: 3(min)'){|v| time_color = v.to_f} opt.on('-s', '--[no-]start', 'default: no'){|v| start = v} opt.banner << "\nLeft upper topmost timer" begin # rescue OptionParser::ParseError => evar opt.parse! rescue OptionParser::ParseError => evar evar.display $stderr; "\n".display $stderr opt.help.display $stderr exit 1 end # rescue OptionParser::ParseError => evar end # ARGV.options do |opt| begin # rescue SystemStackError => evar #VRLocalScreen.start LTTimer lt = VRLocalScreen.showForm LTTimer lt.timer.time_out = time_out lt.timer.time_color = time_color lt.timer.start if start VRLocalScreen.messageloop rescue SystemStackError => evar end # rescue SystemStackError => evar
WindowsでVisualuRuby を使って時間(分秒)表示する GUI時計を作ります。一応 5分計で、途中 3分から表示色を赤っぽくし始め 5分で赤くします。コマンドラインオプションからその辺のタイミングを設定するのはOptionParser (optparse) です。
その表示色なんですが 3分から RGBの値を変えていくのに、実際のところ 3分では全然分かりません。3分半でもしかしてら色変えてますかという程度。4分でそれは褐色かもと見えるようになり、4分半でかなり赤く、そして4分45秒くらいでもう真っ赤、そのまま 5分以降も赤いです。
以下、順次メモ書き。
Version とか require
#coding:Windows-31J # $Id: LT_timer.rb 3582 2010-07-04 09:32:14Z hs9587 $ # $Date: 2010-07-04 18:32:14 +0900 (譌・, 04 7 2010) $ # $Name$ $Author: hs9587 $ $Revision: 3582 $ Version = "0.0 ($Revision: 3582 $)" require 'vr/vruby' require 'vr/vrcontrol' require 'vr/vrtimer' require 'vr/vrlayout' require 'time' Min = Time.parse('00:01')-Time.parse('00:00')
Version定数は後で OptionParser (optparse) の --version 表示に拾って貰う用、subversion の更新文字列を混ぜてる。
そして VisuzluRuby関係の require、vruby は全体的なもの、vrcontrol は釦とか使うので、vrtimer はタイマーの自動画面更新用、vrlayout は釦を配置するときのレイアウトマネージャー。
time はそして Min = 60 の計算用、一分が60秒ってのは即値で書いちゃってもいいのかな。定数 Min の名前はちょっと迷う、最小とか誤解しないか、でもあんまり長いのもなんだし。
タイマー表示のVRコントロール
class TimerControl < VRPanel
タイマー表示の導入
class TimerControl < VRPanel include VRTimerFeasible include VRDrawable SrartResetStruct= Struct.new :name, :button, :body StartReset = [ SrartResetStruct.new('start', '!' \ , lambda{@start_time = Time.now; def anchor_time; @start_time; end}), SrartResetStruct.new('reset', '0' \ , lambda{def anchor_time; Time.now; end}), SrartResetStruct.new('exit', '.', lambda{exit}), ] attr_writer :time_out, :time_color
include はまあそんな感じ。Struct構造体を定義しての StartReset配列にはこの後のコントロール釦の名前や表示、動作を登録する。このコントロールを含む三つのクラス(モジュール)定義で共用するものなので一箇所に登録する。lambdaブロックの動作の為か、このクラス内で定義しないとうまく動かなかったのでここに。
釦の動作は、exitはまあ良いとして、あとの二つは後ろの方で定義するプライベートメソッド anchor_time の再定義。釦押下時点を記録してその時間を返すか、現在時刻を返すか。
そして :time_out, :time_color はコマンドラインオプションからやってきたりする文字色変更のタイミング、というかタイマー期限。
コンストラクタとフォントの事
def construct self.caption = 'LTTimer' #addTimer 1000 addTimer 50 @font = @screen.factory.newfont 'MS ゴシック', -72 #@font = @screen.factory.newfont 'HG ゴシックE', -72 #@font = @screen.factory.newfont 'HGS ゴシックE', -72 #@font = @screen.factory.newfont 'Tahoma', -72, 400, 0, 0, 0, 34, 0 #@font = @screen.factory.newfont 'Tahoma', -72 @time_out = 5.0 @time_color = 3.0 end # def construct
コンストラクタの意義としては addTimer かな。あんまり長いと秒表示のずれがひどいし短いとちらつく。もう少しだけ長くてもいいかも。コメントアウトしてる 1000 は参考にした「フォントを選べる時計」での値。
とはいえそれを参考にしてもフォントの指定方法は良く分からなかったので 'MS ゴシック' 72サイズ。本当は Tahoma とか使いたかったんだけどどうも位置がずれる、大体「-72」の「-(マイナス)」って何だ。
分秒の表示
def self_paint elapse = Time.at((Time.now - anchor_time).abs) self.textColor = RGB elapsed(elapse), 0, 0 mm_ss = elapse.strftime '%M:%S' setFont @font #p textExtent(mm_ss) drawText mm_ss, 0,0, *textExtent(mm_ss) end # def self_paint def self_timer refresh end
実際の表示と再表示、メソッド名は VisualuRuby に従うもの。
表示時間は achor_timeプライベートメソッドと現在時刻の差、achor_timeメソッドの動作によってタイマーが進むのか止まってるのか決まる。そしてそれを elapsedプライベートメソッドに渡して文字色を調整する。
コントロール系のメソッド
StartReset.each do |start_reset| define_method start_reset.name, start_reset.body end # StartReset.each do |start_reset|
釦押下時の動作(メソッド)を定義、前掲配列を当たって三つ。
プライベートメソッド
private def anchor_time Time.now end # def anchor_time def elapsed(sec) sec = sec.to_i case sec when 0 ... Min*@time_color then 0 when Min*@time_color ... Min*@time_out then 256 * (sec - Min*@time_color) / (Min*(@time_out - @time_color)) else sec < 0 ? 0 : 255 end # case sec end # def elapsed(sec) end # class TimerControl < VRPanel
タイマー開始時を返す anchor_time と、タイマー経過時間に対して文字色を返す elapsed。色の計算には起動時にセットされるインスタンス変数 @time_out, @time_color を用いる
操作用釦のVRコントロール
class StartResetControl < VRPanel include VRVertLayoutManager include VRStdControlContainer def construct TimerControl::StartReset.each do |start_reset| addControl VRButton, start_reset.name, start_reset.button send_parent start_reset.name, 'clicked' end # TimerControl::StartReset.each do |start_reset| end # def construct end # class StartResetControl < VRPanel
レイアウトマネージャを使って釦を配置、釦定義には前掲配列を当たる。
タイマー本体
module LTTimer attr_reader :timer def construct self.caption = 'LTTimer' move 0,0, 198,104 addControl TimerControl, 'timer', 'Timer', 0,0, 180,72 addControl StartResetControl, 'buttons', 'Buttons', 181,0, 10,72 top 0xffffffff end # def construct TimerControl::StartReset.each do |start_reset| define_method("buttons_#{start_reset.name}_clicked") do @timer.send start_reset.name end # define_method("buttons_#{start_reset.name}_clicked") do end # TimerControl::StartReset.each do |start_reset| end # module LTTimer
本体の定義、既に定義したタイマー表示部分と釦配置の二つのコントロールを配置する。サイズは即値でここに書く、表示してみないと表示領域の大きさが分からないのでいろいろやってみた。大きさ動的にとるの難しい。あと、top の指定でタイマーを最前面表示する。
それとやはり前掲配列を当たって、釦のコントローラから釦押下を受け取ってタイマー表示のコントローラに受け渡すメソッドを定義。タイマー表示のコントローラは @timerインスタンス変数にいれてる。
コマンドラインとオプション変数
time_out, time_color, start = 5, 3, false require 'optparse' ARGV.options do |opt| opt.on('-o', '--timeout=VAL', 'default: 5(min)'){|v| time_out = v.to_f} opt.on('-c', '--timecolor=VAL', 'default: 3(min)'){|v| time_color = v.to_f} opt.on('-s', '--[no-]start', 'default: no'){|v| start = v} opt.banner << "\nLeft upper topmost timer" begin # rescue OptionParser::ParseError => evar opt.parse! rescue OptionParser::ParseError => evar evar.display $stderr; "\n".display $stderr opt.help.display $stderr exit 1 end # rescue OptionParser::ParseError => evar end # ARGV.options do |opt|
optparse を使ってコマンドラインオプションを受け取る。文字色を変えるタイミングと起動時にタイマーをスタートさせてるか止めてるかの選択。opt.banner にて Usage文字列に説明を付加。
実行
begin # rescue SystemStackError => evar #VRLocalScreen.start LTTimer lt = VRLocalScreen.showForm LTTimer lt.timer.time_out = time_out lt.timer.time_color = time_color lt.timer.start if start VRLocalScreen.messageloop rescue SystemStackError => evar end # rescue SystemStackError => evar
セットされたコマンドオプションを設定して .messageloopを起動。オプションを設定する必要があるのでコメントアウトしてるような .startで一気に実行というのはない。
exit を呼ぶとちょっと階層深くなってるのか SystemStackError が発生するので begin rescue で囲ってある。
VisualuRuby
GUI表示には、Windows という事で VisualuRuby(VisualuRuby計画(仮称))を用いた。なかなか説明とか資料が見付からなくて苦労する。上記プロジェクトのページと、そこにも記載のあるサンプル(VisualuRuby計画(仮称) サンプル)を参考に考える。
SystemStackErrorのこと(/7/25 追記)
メイン(実行)パートの SystemStackError だけど単純な僕の間違いだった。
StartReset定数の3項目
SrartResetStruct.new('exit', '.', lambda{exit}),
これは TimerControlコントローラの中ではメソッド定義に用いる。その実行ブロックでは「Kernel.#exit」メソッドを呼んでプログラム全体を終了しようとするつもりのに、メソッド名自体を「exit」にしてるので自身を呼ぶ事になって循環してしまう。そしてこのエラーになる。
ということで StartReset定数は書き換え、メソッド名は「close」にでもしましょう。
StartReset = [ SrartResetStruct.new('start', '!' \ , lambda{@start_time = Time.now; def anchor_time; @start_time; end}), SrartResetStruct.new('reset', '0' \ , lambda{def anchor_time; Time.now; end}), SrartResetStruct.new('close', '.', lambda{exit}), ]
そしてメイン(実行)ブロックは begin, rescue節で囲う事もなく。
#VRLocalScreen.start LTTimer lt = VRLocalScreen.showForm LTTimer lt.timer.time_out = time_out lt.timer.time_color = time_color lt.timer.start if start VRLocalScreen.messageloop
Windows7 での細々した設定
Windows 7 Professional (64bit版) を使い始めた。で、初期設定とか細々した辺り、先週志村 (@hs9587) | Twitterしたものから転載(誤字ちょっと修正)。
ログオン時の背景画像の変更、C:\windows\System32\oobe\info\BACKGROUNDS\BACKGROUNDDEFAULT.JPG を同名の別 jpeg画像ファイルに差し替える。大きさ制限 250Kまで、とか、かも。 Windows7 2:29 PM Nov 27th webで
ファイル拡張子の表示。コントロールパネル-デスクトップのカスタマイズ-フォルダーオプション-表示-詳細設定-登録されている拡張子は表示しない、のチェックを外す。 Windows7 8:16 PM Nov 26th webで
他にも隠しファイルの表示非表示とかその辺りはこの辺に。
ログイン時のユーザ名表示の抑制。コントロールパネル-システムとセキュリティ-管理ツール-ローカルセキュリティポリシー-ローカルポリシー-セキュリティオプション-対話型ログオン: 最後のユーザー名を表示しない-プロパティ、で有効に設定。140字以内で書けた! Windows7 5:35 PM Nov 26th webで
パスワードの長さ難さとかその辺りもこの辺。
取り敢えずマウス調整、早くする。ポインター画像、待ちは最初からアニメーションだった、ドーナツぐるぐる、Windows7 3:30 PM Nov 26th webで
Windows7(64bit)始めました。でもなんだかよく分かりません、混乱しています。 2:59 PM Nov 26th webで
PGconn#quote_ident の有無
昨日 PGconn#quote_ident - Rubyとか Illustratorとか SFとか折紙とか の続き。
大事な事、Debian lenny で libpgsql-ruby を使ってた方は大丈夫だったです、他でも新しめの環境なら大丈夫なのでしょう。
- Rails(ActiveRecord) 2.3.3 <- 2.3.2 のヴァージョンアップで、activerecord-2.3.#/lib/active_record/connection_adapters/postgresql_adapter.rb の中の quote_column_name(name)メソッドの実装が変わった
- 単に「%("#{name}")」としていたものから「PGconn.quote_ident(name.to_s)」へ
- Debian の libpgsql-ruby1.8 の提供する Rubyライブラリは lenny では pg.so だが、etch では postgres.so たった
- postgres.so の提供する PGconnクラスに所要の quote_ident は定義されていない
- それはそれとして上記 postgresql_adapter.rb 冒頭ではまずライブラリでかジェムでか知らず 'pg' を requireしようとし、駄目だったら 'postgres' を requireする(そしてメソッド名とかちょこっと調整する)
という訳で、未だに Debian etch を引きずってるのが駄目だった模様。
etchの場合
そういうわけで、ActiveRecord(postgresql_adapter.rb) のライブラリ切換えを利用することにして、site_ruby にちょっと pg.rb とか置いて誤摩化す。これで Railsアプリケーションレベルでの昨日みたいなちょっとなんとかはせずに済むようになる。
/usr/local/lib/site_ruby/pg.rb
require 'postgres' class PGconn unless self.respond_to? :quote_ident then def self.quote_ident(name) '"' + name + '"' end # def self.quote_ident(name) end # unless self.respond_to? :quote_ident end # class PGconn class PGresult alias_method :nfields, :num_fields unless self.method_defined?(:nfields) alias_method :ntuples, :num_tuples unless self.method_defined?(:ntuples) alias_method :ftype, :type unless self.method_defined?(:ftype) alias_method :cmd_tuples, :cmdtuples unless self.method_defined?(:cmd_tuples) end # class PGresult
site_ruby か site_ruby/1.8 か、或いは vender_ruby以下とかは大変迷う。 PGresult方面は上記 postgresql_adapter.rb 冒頭での調整事項、ここが繰り返しになるのはちょっとやなんだけどね
Windowsの場合
こっちの方ではポスグレのドライバーとしては gem の postgres-pr を使っている (PostgreSQLサーバ自体は近在の Linux機)。そして gem の postgres はコンパイル不能でやっぱりインストール出来ない。「Could not find PostgreSQL build environment (libraries & headers): Makefile not created」
上記 etch での措置と同じやり方でも誤魔化せそうなんだけど折角 postgres-pr というちょっとだけ違う名前が使えるのでなんかやってみる。
C:\Program Files\ruby-1.8\lib\ruby\site_ruby\postgres.rb
require 'rubygems' require 'postgres-pr/postgres-compat' class PGconn unless self.respond_to? :quote_ident then def self.quote_ident(name) '"' + name + '"' end # def self.quote_ident(name) end # unless self.respond_to? :quote_ident end # class PGconn
postgres-prジェムの入れる postgres.rb は乗っ取ってしまうがその中でやってるのは postgres-pr/postgres-compat の呼び出しなのでそれを代行。rubygems を require しておくべきかどうかは微妙だが、いつもいつも Rails方面からの require だけでもあるまいと考えて。
pg として振舞うわけではだいので etch の時のようなメソッド名調整は無くて良い、そこはちょっとすっきりした。
関係ないけど rake cucumber:all
関係ないけどそんなことしてる間に「rake features」は時代遅れになっていた。「rake cucumber:all」だって、あと「ok」「wip」(work in progress 絶賛開発中)モードとか。
gem update と rubygems-update (1.3.3)
Windows での「gem update」の際、sqlite3-ruby など、ネイティヴ拡張が必要なのに Windowsなのでコンパイルできなくてアップデートに失敗する者があると、そこでアップデート作業が終わってしまい(恐らくアルファベット順で)その順番以降の gem のアップデートが行われなかった。
仕方ないので「gem list」からジェム名称を拾って個別に「gem update <ジェム名称>」してたものだ。
ジェムのアップデートに伴ない、1.3.3 からはそんなことしなくても良くなった。一つのジェムがアップデートに失敗しても、ジェムのアップデート作業はずっと続いて最後まで実行してくれる。まあ、失敗した者は入らない(アップデートされない)けど。
ちょっと便利になったかな、と言うか少し不便が無くなったのか。
>gem --version 1.3.3
Racc のインストール (/1.9.1)
WindowsXP(Sp3)にて、Ruby は artionさんの 1.9.1 (ActiveScriptRuby and Other packagesより Ruby-1.9.1-p0)、gem を 1.3.2 にアップデートしたら racc のインストールがうまくいかなくなった。というか、それ以前からインストールは途中で失敗する感じなんだけど、raccコマンド自体は動作するので問題にしていなかった。それが、gem のバージョンチェックが厳しくなったのか、動かなくなった。「:in `bin_path': can't find gem racc ([">= 0"])」
「gem install racc」のエラーはこんな感じ
Building native extensions. This could take a while... ERROR: Error installing racc: ERROR: Failed to build gem native extension. C:/PROGRA~1/RUBY-1~1.1/bin/ruby.exe extconf.rb extconf.rb:3:in ``': No such file or directory - uname -p (Errno::ENOENT) from extconf.rb:3:in `'
ちなみに
<云々>>gem --version 1.3.2
C:\Program Files\Ruby-1.9.1\lib\ruby\gems\1.9.1\gems\racc-1.4.6 とかにいって「ruby setup.rb」しても同じ所でエラーになる(エラーメッセージはもう少し詳しい)。「ruby setup.rb config」でも同じエラー。
ということで、同所 README.ja.rdoc の示唆に従い、「--without-ext」してみる。
<云々>1.9.1\lib\ruby\gems\1.9.1\gems\racc-1.4.6>ruby setup.rb config --without-ext
-
-
- > bin
-
-
-
- > lib
- > lib/racc
-
こんどはエラーない、つづけて「setup」「install」、いちいち「skipping ext/* by user option」といわれるがインストール成功。
<云々>>racc --version racc version 1.4.6
できた。しかし、gem list には載ってこない。gemコマンド方面でもこんな感じにインストールオプション渡してインストール出来るのかな?
あと、extなしというのは、racc の解析機 parse に、C版が使えず、ピュアRuby版を使う事になるのでちょっと遅くなるかもです。切り替えは自動なのであんまり意識する事はないかもしれない。
全角マイナスの問題
あんまりカテゴリが多いのも頭悪そうなんだが、実際頭の悪い問題なので。あと、全角と言う表現も頭悪いし。
現象
詳細
Linux(UTF-8環境)の 1.8系Ruby の irb で確かめてみる
- Linuxに Windows機の PuTTY端末から、全角マイナスを入力
- 1.8系Ruby的には "\357\274\215"
- それを NKF.nkf '-W -s', で変換する、シフトJISの全角マイナス
- 1.8系Ruby的には "\201|"
- この縦棒はなんだよ、\174 です
- 1.8系Ruby的には "\201|"
- それを NKF.nkf '-S -w', で変換する、UTF-8
- 1.8系Ruby的には "\342\210\222"
- それは 1.9Ruby的な "\u2212" と同じ
- それを NKF.nkf '-W -s', で変換する、1.8系Ruby的には "\201|"
- それを NKF.nkf '-S -w', で変換する、1.8系Ruby的には "\342\210\222"
- 安定的になった
Windows環境の方には 1.9コンソールを入れてるのでそのirbでちょっと
"\u2212" は所要のものだ
irb(main):039:0> "\u2212".force_encoding('UTF-8').each_byte{|b| puts '%o'%b } 342 210 222 => "竏・
"\357\274\215"だって間違ってるわけじゃない
irb(main):040:0> "\357\274\215".force_encoding('UTF-8').valid_encoding? => true
変換は出来ないけど
irb(main):041:0> "\357\274\215".force_encoding('UTF-8').encode('Shift_JIS') Encoding::UndefinedConversionError: "\xEF\xBC\x8D" from UTF-8 to Shift_JIS from (irb):41:in `encode' from (irb):41 from C:/Program Files/Ruby-1.9.1/bin/irb.bat:20:in `<main>'
NKFなら変換できる
irb(main):044:0> NKF.nkf('-W -s', "\357\274\215".force_encoding('UTF-8')).each_byte{|b| puts '%o'%b } 201 174 => "−"
事情
普通に Debian GNU/Linux 上で Railsアプリケーションを作っていた。一部出力として Shift_JIS が欲しい(何かの結果のテキストのファイルダウンロードサービス)ということだったので、NKF で変換して出すようにした。
スペック(rspec-raile)を取ろうとした、まあ住所っぽいもので全角文字使用(半角文字は使わない)なので番地の区切りに全角マイナスを使ってみた。(実際そういう入力がある)
スペック自体は Linux上で実行するので、比較する文字列なんかは UTF-8 でスペックファイルに書いてある方が見易い。だから全部 UTF-8 に再変換してからマッチャ呼ぶことにした。
すると合わない、マッチャが通らない。どうしよう。
と言う事で調べた。
@ruby.exe -Ku racc <文法ファイル名>
Windows での、Racc文法ファイルの文字コードの扱いについて、前の項(Windowsで 1.9.1 と Racc とスクリプトエンコーディング - Rubyとか Illustratorとか SFとか折紙とか)の機序もう少し詳しく見てみる、「るびま」を参考に。
文法ファイルには UTF-8文字が混じっているという状況
まず、「-Ku」の無い場合
- racc <文法ファイル名>
- Windowsが racc.bat を探し当ててそれを実行
- ruby.exe racc <文法ファイル名> を実行
- <文法ファイル名>ファイルを読む、default_external = Windows-31J と想定
- UTF-8文字列が出てきたら、想定が違うとエラー
「-Ku」付きの場合
- racc -Ku <文法ファイル名>
- Windowsが racc.bat を探し当ててそれを実行
- ruby.exe -Ku racc <文法ファイル名> を実行
- <文法ファイル名>ファイルを読む、default_external = UTF-8 と想定
- UTF-8文字列が出てきても大丈夫
- default_internal が nil なので、文法ファイル文字列は内部的にも UTF-8 (externalと同じ)
こんな感じかな、間違ってないよね。
前項では、スクリプトエンコーディングという言葉を出したけど、微妙に適切ではなかったかも。