我正在开发一个项目,我有一个动态确定的挂载点,并提供了一组绝对路径来处理目标卷。由于这些文件尚不存在,我使用Pathname类来处理文件名操作。但是,在连接具有相同根的路径时,Pathname似乎做了一些聪明的事情。我观察到以下行为:
p1 = Pathname.new('/foo/bar') # #<Pathname:/foo/bar>
p2 = Pathname.new('/baz/quux') # #<Pathname:/baz/quux>
p3 = p1 + p2 # #<Pathname:/baz/quux>
p4 = p1.join p2.relative_path_from(Pathname.new('/')) # #<Pathname:/foo/bar/baz/quux>
p5 = Pathname.new(p1.to_s.concat p2) # #<Pathname:/foo/bar/baz/quux>
所以使用p4和p5,我能够得到我想要的行为,但结构有点人为。有更清洁的方法吗?
答案 0 :(得分:4)
来自fine manual:
<强> +(其它)强>
路径名#+将路径名片段附加到此路径名以生成新的路径名对象。
p1 = Pathname.new("/usr") # Pathname:/usr p2 = p1 + "bin/ruby" # Pathname:/usr/bin/ruby p3 = p1 + "/etc/passwd" # Pathname:/etc/passwd
强调我的。指定Pathname的+
运算符以附加路径名片段,但带有前导斜杠的路径名不是片段。如果您尝试添加两个路径名或将非片段添加到路径名,但文档没有明确指定应该发生什么,但示例意味着您看到了预期的行为。
答案 1 :(得分:4)
使用字符串操作解决Ruby的奇怪行为相当容易。
借用OP的例子......
p1 = Pathname.new('/foo/bar')
p2 = '/baz/quux'
p1 + p2.sub(/\A\//, '')
# => #<Pathname:/foo/bar/baz/quux>
警告:第二个p2
必须是String
才能进行sub
操作。您可以使用Pathname
轻松转换#to_s
对象。
Pathname.new('/some/path/').to_s
# => "/some/path"