🚀
[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