Bug #7881

Windows でパスに日本語を含むスクリプトからの require が失敗する

Added by 5 5 about 1 year ago. Updated about 1 year ago.

[ruby-dev:47042]
Status:Assigned
Priority:Normal
Assignee:Hiroshi Shirosaki
Category:core
Target version:next minor
ruby -v:ruby 1.9.3p385 (2013-02-06) [i386-mingw32] Backport:

Description

=begin
Windows でパスに日本語を含むスクリプトからの require が失敗します。

Ruby 1.9.3 の p374,p385 でこの現象が起こりますが,p125 では起こりません。
p286 あたりから起こるようになったと思います。

【再現手順】
(1) d:/テスト というフォルダーを作る。
(2) d:/テスト/a.rb を下記のように書く。
(3) d:/テスト/b.rb を下記のように書く。
(4) cd /テスト
(5) ruby a.rb

a.rb の内容:

# encoding: utf-8
require "./b"

b.rb の内容

# encoding: utf-8
puts "No problem."

これで,

cannot load such file -- ./b (LoadError)

が出ます。

  • フォルダー名を「テスト」から「test」に変えると正常に動作します。
  • a.rb のスクリプトエンコーディングを CP932 に変えると正常に動作します。
  • require "./b" を require "./b".encode("CP932") に変えると正常に動作します。
  • 標準添付ライブラリーや gem はふつうに require できます。

=end

History

#1 Updated by Koichi Sasada about 1 year ago

  • Category set to core
  • Assignee set to Usaku NAKAMURA

usa さんか naruse さんかわからなかったんですが、とりあえず usa さんへアサイン。

#2 Updated by Usaku NAKAMURA about 1 year ago

  • Status changed from Open to Assigned
  • Assignee changed from Usaku NAKAMURA to Hiroshi Shirosaki

なんとなく、いつぞやのWindowsのrequire高速化関連のような気もするのですが、
しろさきさん何かわかったりしますか?

その前の奴かなあ?

#3 Updated by Yui NARUSE about 1 year ago

  • Target version changed from 1.9.3 to next minor

#4 Updated by Hiroshi Shirosaki about 1 year ago

=begin
Windowsのexpand_pathのencodingのバグのようです。

osxだとcurrent directoryのpathに日本語を含むかどうかでencodingがかわるので、Windowsもそのように修正したいと思います。

$ cat testexpandpath.rb
# coding: sjis
p File.expandpath("./a")
p File.expand
path("./a").encoding
$ ruby -v testexpandpath.rb
ruby 2.1.0dev (2013-02-27 trunk 39526) [x8664-darwin12.2.0]
"/Users/hiroshi/work/a"
#Encoding:Windows-31J
$ cd あああ
$ ruby -v ../test
expandpath.rb
ruby 2.1.0dev (2013-02-27 trunk 39526) [x86
64-darwin12.2.0]
"/Users/hiroshi/work/あああ/a"
#Encoding:UTF-8
=end

#5 Updated by Usaku NAKAMURA about 1 year ago

=begin
あれ、これはWindowsでは互換性のためにわざと常にlocaleでexpand_pathされるようにしておいたような記憶があるのですが。

そろそろこの仕様を変えるのはアリだとは思いますが、1.9.3はちょっと意図的ではないので元の挙動に戻したいです。
2.0.0は... 現状優先なのかなあ。

C:> type a.rb
# coding: utf-8
unless ''.respondto?("encoding")
class String
def encoding
"dummy"
end
end
end
path = File.expand
path("./a")
p [path, path.encoding]

C:> ruby187p371 -v a.rb
ruby 1.8.7 (2012-10-12 patchlevel 371) [i386-mswin32]
["C:/a", "dummy"]

C:> ruby193p0 -v a.rb
ruby 1.9.3p0 (2011-10-30 revision 33570) [x64-mswin64_100]
["C:/a", #Encoding:Windows-31J]

C:> ruby193p392 -v a.rb
ruby 1.9.3p392 (2013-02-22 revision 39386) [x64-mswin64_100]
["C:/a", #Encoding:UTF-8]

C:> ruby200p0 -v a.rb
ruby 2.0.0p0 (2013-02-24 revision 39474) [x64-mswin64_100]
["C:/a", #Encoding:UTF-8]

C:> cd てすと

C:\てすと> ruby187p371 -v a.rb
ruby 1.8.7 (2012-10-12 patchlevel 371) [i386-mswin32]
["C:/\202\304\202\267\202\306/a", "dummy"]

C:\てすと> ruby193p0 -v a.rb
ruby 1.9.3p0 (2011-10-30 revision 33570) [x64-mswin64_100]
["C:/てすと/a", #Encoding:Windows-31J]

C:\てすと> ruby193p392 -v a.rb
ruby 1.9.3p392 (2013-02-22 revision 39386) [x64-mswin64_100]
["C:/\u3066\u3059\u3068/a", #Encoding:UTF-8]

C:\てすと> ruby200p0 -v a.rb
ruby 2.0.0p0 (2013-02-24 revision 39474) [x64-mswin64_100]
["C:/\u3066\u3059\u3068/a", #Encoding:UTF-8]
=end

#6 Updated by Hiroshi Shirosaki about 1 year ago

usa (Usaku NAKAMURA) wrote:

あれ、これはWindowsでは互換性のためにわざと常にlocaleでexpand_pathされるようにしておいたような記憶があるのですが。

1.9.3のunixでは常にlocaleになるように修正されていましたが、windowsではbackportするときには、そのまま(2.0.0と同じ)で手は入れられていないのではないでしょうか。

encodingを常にfile system encodingにするのは、たぶん以下の行以降のcpとpath_encodingをfile system encodingにすればよいと思います。
https://github.com/ruby/ruby/blob/trunk/win32/file.c#L584

そろそろこの仕様を変えるのはアリだとは思いますが、1.9.3はちょっと意図的ではないので元の挙動に戻したいです。
2.0.0は... 現状優先なのかなあ。

C:\てすと> ruby200p0 -v a.rb
ruby 2.0.0p0 (2013-02-24 revision 39474) [x64-mswin64_100]
["C:/\u3066\u3059\u3068/a", #Encoding:UTF-8]

trunkのosxでの動作から考えると、このencodingがWindows-31Jになるのがよいと思ったのですが、現状がよいのでしょうか?

#7 Updated by Usaku NAKAMURA about 1 year ago

こんにちは、なかむら(う)です。

In message " [ruby-trunk - Bug #7881] Windows でパスに日本語を含むスクリプトからの require が失敗する"
on Feb.27,2013 20:38:05, h.shirosaki@gmail.com wrote:

あれ、これはWindowsでは互換性のためにわざと常にlocaleでexpand_pathされるようにしておいたような記憶があるのですが。

1.9.3のunixでは常にlocaleになるように修正されていましたが、windowsではbackportするときには、そのまま(2.0.0と同じ)で手は入れられていないのではないでしょうか。

意図を示すテストがないせいで気付かなかったのですかねえ。
あとで本当にテストがなかったのかどうか探そう。

encodingを常にfile system encodingにするのは、たぶん以下の行以降のcpとpath_encodingをfile system encodingにすればよいと思います。
https://github.com/ruby/ruby/blob/trunk/win32/file.c#L584

ありがとうございます。

そろそろこの仕様を変えるのはアリだとは思いますが、1.9.3はちょっと意図的ではないので元の挙動に戻したいです。
2.0.0は... 現状優先なのかなあ。

C:\てすと> ruby200p0 -v a.rb
ruby 2.0.0p0 (2013-02-24 revision 39474) [x64-mswin64_100]
["C:/\u3066\u3059\u3068/a", #Encoding:UTF-8]

trunkのosxでの動作から考えると、このencodingがWindows-31Jになるのがよいと思ったのですが、現状がよいのでしょうか?

意図はともかく挙動は変わっちゃってるので、あえてバグだと言わ
ずに仕様だと押し切った方が将来楽かも、とか。

まあ、あんまり強い意見はないので、2.0.0メンテナの近永さんと相
談ですかねえ。

それでは。
--
U.Nakamura usa@garbagecollect.jp

#8 Updated by Tomoyuki Chikanaga about 1 year ago

素朴にバグかと思っていたのですが、File.expand_path の今現在の挙動のほうが望ましい場面っていうのは考えられるんでしょうか。

#9 Updated by Hiroshi Shirosaki about 1 year ago

=begin

たとえば、下記のようなコードを書いたときに、current directoryのパスが日本語を含んでいても
Encoding::CompatibilityError にならずに動く、という利点はあるのではないでしょうか。

expand_pathの結果がfilesystem encodingに変わる可能性があれば、日本語の引数に.encode('filesystem')をつけるなどしておかないといけません。

# coding: euc-jp

expand = File.expand_path('あ')
p [expand, expand.encoding]
path = File.join(expand, "あああ")
p [path, path.encoding]

あと、報告のあったrequire "./b" に関しては require_relative "b" でも動作するようです。

=end

Also available in: Atom PDF