Combining absolute paths with the Pathname class

I am working on a project where I have a dynamically defined mount point, and I have provided a set of absolute paths to work on the target volume. Since these files do not yet exist, I use the Pathname class to handle file name manipulations. However, Pathname seems to do something a little smart when it comes to concatenating paths that have the same root. I 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 can get the behavior I wanted, but the constructs are a bit far-fetched. Is there a cleaner way to do this?

+4
source share
2 answers

From the exact guide :

+ (other)

Pathname # + adds a fragment of the path to this to create 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 

The emphasis is mine. The + operator for Pathname is specified to add fragments of a path, but a path with a leading slash is not a fragment. The documentation does not explicitly state what should happen if you try to add two paths or add a non-fragment to Pathname, but the examples imply that you see the expected behavior.

+4
source

It’s pretty simple to work with the odd behavior of Ruby using string manipulations.

Borrowing an OP Example ...

 p1 = Pathname.new('/foo/bar') p2 = '/baz/quux' p1 + p2.sub(/\A\//, '') # => #<Pathname:/foo/bar/baz/quux> 

Caution: The second p2 must be a String to perform a sub operation. You can easily convert the Pathname object using #to_s .

 Pathname.new('/some/path/').to_s # => "/some/path" 
+4
source

Source: https://habr.com/ru/post/1434669/


All Articles