I am working on a project where I have a dynamically determined mount point and am provided a set of absolute paths to do work on on the target volume. Since these files don't exist yet, I am using the Pathname class to handle the filename manipulations. However, Pathname seems to be doing something a bit clever when it comes to concatenating paths that have the same root. I have observed the following behavior:
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>
So with p4 and p5, I am able to get the behavior I wanted, but the constructions are a little contrived. Is there a cleaner way to do this?
It's fairly easy to work around Ruby's odd behavior here using string manipulation.
Borrowing the OP's example...
p1 = Pathname.new('/foo/bar')
p2 = '/baz/quux'
p1 + p2.sub(/\A\//, '')
# => #<Pathname:/foo/bar/baz/quux>
Caveat: The second p2
must be a String
in order for the sub
operation to occur. You can easily convert a Pathname
object using #to_s
.
Pathname.new('/some/path/').to_s
# => "/some/path"
From the fine manual:
+(other)
Pathname#+ appends a pathname fragment to this one to produce a new Pathname object.
p1 = Pathname.new("/usr") # Pathname:/usr p2 = p1 + "bin/ruby" # Pathname:/usr/bin/ruby p3 = p1 + "/etc/passwd" # Pathname:/etc/passwd
Emphasis mine. The +
operator for Pathname is specified to append pathname fragments but a pathname with a leading slash is not a fragment. The documentation doesn't explicitly specify what is supposed to happen if you try to add two pathnames or add a non-fragment to a Pathname but the examples imply that you're seeing the expected behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With