Bug #7881
closedWindows でパスに日本語を含むスクリプトからの require が失敗する
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
Updated by ko1 (Koichi Sasada) over 11 years ago
- Category set to core
- Assignee set to usa (Usaku NAKAMURA)
usa さんか naruse さんかわからなかったんですが、とりあえず usa さんへアサイン。
Updated by usa (Usaku NAKAMURA) over 11 years ago
- Status changed from Open to Assigned
- Assignee changed from usa (Usaku NAKAMURA) to h.shirosaki (Hiroshi Shirosaki)
Updated by naruse (Yui NARUSE) over 11 years ago
- Target version changed from 1.9.3 to 2.6
Updated by h.shirosaki (Hiroshi Shirosaki) over 11 years ago
=begin
Windowsのexpand_pathのencodingのバグのようです。
osxだとcurrent directoryのpathに日本語を含むかどうかでencodingがかわるので、Windowsもそのように修正したいと思います。
$ cat test_expand_path.rb
coding: sjis¶
p File.expand_path("./a")
p File.expand_path("./a").encoding
$ ruby -v test_expand_path.rb
ruby 2.1.0dev (2013-02-27 trunk 39526) [x86_64-darwin12.2.0]
"/Users/hiroshi/work/a"
#Encoding:Windows-31J
$ cd あああ
$ ruby -v ../test_expand_path.rb
ruby 2.1.0dev (2013-02-27 trunk 39526) [x86_64-darwin12.2.0]
"/Users/hiroshi/work/あああ/a"
#Encoding:UTF-8
=end
Updated by usa (Usaku NAKAMURA) over 11 years ago
=begin
あれ、これはWindowsでは互換性のためにわざと常にlocaleでexpand_pathされるようにしておいたような記憶があるのですが。
そろそろこの仕様を変えるのはアリだとは思いますが、1.9.3はちょっと意図的ではないので元の挙動に戻したいです。
2.0.0は... 現状優先なのかなあ。
C:> type a.rb
coding: utf-8¶
unless ''.respond_to?("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
Updated by h.shirosaki (Hiroshi Shirosaki) over 11 years 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になるのがよいと思ったのですが、現状がよいのでしょうか?
Updated by usa (Usaku NAKAMURA) over 11 years ago
こんにちは、なかむら(う)です。
In message "[ruby-dev:47123] [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
Updated by nagachika (Tomoyuki Chikanaga) over 11 years ago
素朴にバグかと思っていたのですが、File.expand_path の今現在の挙動のほうが望ましい場面っていうのは考えられるんでしょうか。
Updated by h.shirosaki (Hiroshi Shirosaki) over 11 years 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
Updated by jeremyevans0 (Jeremy Evans) over 5 years ago
- Status changed from Assigned to Closed
This appears to have been fixed between Ruby 2.4 and 2.5:
D:\テスト>c:\Ruby24-x64\bin\ruby a.rb
a.rb: No such file or directory @ realpath_rec - D:/??? (Errno::ENOENT)
D:\テスト>c:\Ruby25-x64\bin\ruby a.rb
No Problem.