この日記にはツッコミを入れられます。 ツッコミを入れたい日付をクリックすると、フォームが現れます。
xreaでtDiaryを使う方法はxrea.com で tDiary を使う方法やインストールメモやXREA + tDiary + Namazuをどうぞ。
[learn-ruby-in-kansai:1832] Re: 第22回 Ruby/Rails勉強会 お題募集の話をみて、年末年始にEncodingについて調べていたけど、募集締め切りで1.9の話は採用されていなさそうだったので、調べた内容をちょっと書き直して「Ruby 1.9 の Encoding について」として公開してみた。
空前のruby 1.9対応ブーム?
簡単にできる1.8と1.9両対応その1。String#eachの代わりにString#each_lineを使う。
その2。instance_variablesとかのSymbolが返ってくるようになってきているものはto_sでStringに統一する。
その3。環境変数を設定されていない状態にするにはENV[var]にnilを代入せずにENV.delete(var)を使う。
String#to_aは悩ましい。hikiではArrayまたはStringが想定されているところだったので、とりあえず。つっこみを受けて考え直したので追記: respond_to? :to_aでチェックしてto_aがなければsplit(/\r?\n/)するようにしてみたsplitを使うならsplit(/^/)が正解だった。to_aはArray#to_aも存在することを利用しているので、String#linesというのはArrayがきたときに困るので不採用。多重代入が使えそうだったのでいくつかの組み合わせを調べて、結局@sp_path = ( @conf["#{SP_PREFIX}.path"] || "#{PATH}/misc/plugin" ).to_aだったものを*@sp_path = *( @conf["#{SP_PREFIX}.path"] || "#{PATH}/misc/plugin" )にしてみた。
Encoding関連で-Keで起動するとhikiconf.rbの@author_name = '名無しさん'がeuc-jpになっていて、ERBの中の@contents[:footer]をconcatするところでcharacter encodings differになってしまうので、-Knで起動しないと動かない。
また、-Kオプションか-EオプションでEncoding.default_externalを指定しておかないと、Encoding.locale_charmapからEncoding.default_externalがUTF-8になってしまっていて、hikiconf.rbを読み込んだ文字列のencodingがUTF-8になって、evalでinvalid multibyte char (SyntaxError)になってしまった。
1: ArgumentError: character encodings differやinvalid multibyte char (SyntaxError)など。どこでエンコーディングがついているのか悩みまくる。ちゃんとmagic commentを入れたり--encodingを指定したりしないとlocaleによって動いたり動かなかったりすると言うことも起きそう。デバッグ用のpも["あ".encode("utf-8"), "あ".encode("euc-jp")].inspectでcharacter encodings differになったりするので使いにくいかもしれない。
2: String#sizeなどのascii_only?がtrueの時は1.8と同じ挙動に見えるもの。US-ASCIIの範囲内の文字だけでテストすると気づかないバグがたくさん起きそう。特にsizeからbytesizeへの変更はwebrickの修正にあったように末尾が切れて気づくと言うことが多発しそう。File#truncateの引数とかはデータを失う原因になりそうなので要チェックかも。
3: 使っているライブラリが対応してない。hikiの場合はhikidocとdocdiffが...。
他は例外とかですぐに原因がわかることが多い、といいなあ。
プログラムのエンコーディングを指定するmagic commentについて。
ファイルからの読み込みに限らずevalでもmagic commentをみてくれるようなのでちょっと挙動を調べてみた。ascii onlyな文字列だとASCII-8BITにしかならないようなので、適当に\xFFを使ってみた。
magic commentとして受け付けるパターンはemacs用の# -*- coding: utf-8 -*-やvimの# vim:set fileencoding=utf-8:と兼用できるような仕様になっているのだと思う。
仕様としては最初の行(1行目か1行目がrubyを含むshebangなら2行目)の(空白があってもいいけど)行頭からコメントがあって、その中にmagic commentがあるときにascii onlyではない文字列リテラル(や正規表現リテラル)がmagic commentのencodingになるらしい。
ということは正規表現のオプションで直接encodingを指定できるe,s,u以外の正規表現リテラルを書くにはmagic commentが使えばいいと言うことになりそう。
% cat a.rb
def puts_and_eval(code)
puts code
s = eval(code)
puts " => #{s.encoding}\n\n"
end
puts_and_eval <<-'RUBY'
# -*- coding: euc-jp -*-
"\xFF"
RUBY
puts_and_eval <<-'RUBY'
# -*- coding: euc-jp -*-
"\xFF"
RUBY
puts_and_eval <<-'RUBY'
"\xFF"
# -*- coding: euc-jp -*-
RUBY
puts_and_eval <<-'RUBY'
"\xFF" # -*- coding: euc-jp -*-
RUBY
puts_and_eval <<-'RUBY'
#!/usr/bin/ruby
# -*- coding: euc-jp -*-
"\xFF"
RUBY
puts_and_eval <<-'RUBY'
#!/usr/bin/ruby
"\xFF" # -*- coding: euc-jp -*-
RUBY
% ruby-trunk a.rb # -*- coding: euc-jp -*- "\xFF" => EUC-JP # -*- coding: euc-jp -*- "\xFF" => EUC-JP "\xFF" # -*- coding: euc-jp -*- => ASCII-8BIT "\xFF" # -*- coding: euc-jp -*- => ASCII-8BIT #!/usr/bin/ruby # -*- coding: euc-jp -*- "\xFF" => EUC-JP #!/usr/bin/ruby "\xFF" # -*- coding: euc-jp -*- => ASCII-8BIT %
#!/usr/bin/ruby
$longest = 0 # ugly
def siritori(selected_words, rest_words)
word = selected_words[-1]
if word
last_char = word[/.$/]
next_words = rest_words.grep(/^#{last_char}/) # TODO: Regexp.escape
else
next_words = rest_words # first call
end
if next_words.empty?
if selected_words.size >= $longest
$longest = selected_words.size
p [selected_words.size, selected_words]
end
else
next_words.each do |next_word|
siritori(selected_words + [next_word], rest_words - [next_word])
end
end
end
words = $<.read.split(/\W/)
p [words.size, words]
siritori([], words)
✑ naruse [# UTF-16 などは nkf を require すると増える nkf を require すると確かに増えるん..]