🚀
[Bug #21391] File.join と Pathname#join に空文字列を渡したときの挙動が一貫しないバグ報告
[Bug #21391] Inconsistent trailing slash behavior of File.join and Pathname#join with empty strings
- 次のように
File.joinとPathname#joinで空文字列を渡したときに末尾に/が付く付かないで一貫性がないというバグ報告
require "pathname"
# これは末尾に / が付く
p File.join('/usr', '')
# => "/usr/"
# これは末尾に / が付かない
p Pathname.new('/usr').join('').to_s
# => "/usr"
# 空文字列出ない場合は両方とも / が付く
p File.join('/usr', ' ')
# => "/usr/ "
p Pathname.new('/usr').join(' ').to_s
# => "/usr/ "
p Pathname.new('/usr').join('/').to_s
- パスの末尾に
/を追加するのは一般的な使用例で現状だと式展開("#{Rails.root}/")やFile.joinを利用する(File.join(Rails.root, ''))必要があると書かれていますね- これを
Rails.root.join("")で書きたい、ってことがモチベーションなのかな? - どちらかというと空文字列を渡した場合の挙動が明文化されておらず一貫性のない動作になっているのがこのチケットで話したいことみたい
- その上で
Pathname#joinで末尾に/が追加できる明確な方法がほしいみたい - https://bugs.ruby-lang.org/issues/21391#note-3
- これを
- コメントだとこれ以外のケースでもいくつか差異があると指摘されていますね
File.join("/usr","/var") #=> "/usr/var"
Pathname.new("/usr").join("/var").to_s #=> "/var"
File.join("/usr","../var") #=> "/usr/../var"
Pathname.new("/usr").join("../var").to_s #=> "/var"
File.join("/usr","/../var") #=> "/usr/../var"
Pathname.new("/usr").join("/../var").to_s #=> "/../var"
- これは
File.joinは単純に2つの文字列をセパレータ(/)で結合するだけなんですがPathname#joinは2つのパスに対して論理演算しているので違いがあるらしい - ここでいう
論理演算っていうのがあんまりよくわからなかったんですがPathname#joinは『引数でcdした結果』と同等であることを期待しているみたいですね?- なので
/usrでcd ../varすれば/varになるようなイメージ - https://bugs.ruby-lang.org/issues/21391#note-4
- なので
- あとそもそもパスの末尾に
/をつけることは OS間の移植性がなるのでやめたほうがよいともコメントされていますね-
Pathnameの挙動はそれを反映しているらしい
-
- ただ、規格としてこのあたりの状況を修正しようとする動きもあるみたいですねー
Discussion