-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider making File.join handle absolute paths #5904
Comments
It's funny, because I have the opposite expectation: Futhermore, having I believe the current behavior is a correct, expected and safer behavior by default. |
I agree - When running |
I don't agree. File.join should be dumb and simple to understand. I'm certain you should be using expand here. |
@RX14 So what's your recommended method to join a path with another, possibly absolute path using |
I should mention, also, that the approach I'm talking about is indeed very simple to understand - it mirrors every |
We don't provide anything for that. You'll have to come up with your solution. Possibly iterating paths until an absolute one is found and start joining there. For example: def join_paths(*args)
(args.size - 1).downto(1) do |i|
if args[i].starts_with?(File::SEPARATOR)
return File.join(args.to_a[i..-1])
end
end
File.join(args)
end
p join_paths("dir", "sub/path") # => "dir/sub/path"
p join_paths("dir", "/absolute", "sub/path") # => "/absolute/sub/path"
p join_paths("dir", "/whoops", "sub", "/abso") # => "/abso" If all you need is def cd(path)
if path.starts_with?(File::SEPARATOR)
Dir.cd(path)
else
Dir.cd(File.join(Dir.current, path))
end
end I.e. expecting one path to be an absolute path and act upon it in the best manner. This is better than forgetting to sanitize a |
Shouldn't there be a way to join paths intelligently in the stdlib, then? After all, there's a |
If you can come up with a good, reliable, well named solution, that serves a variety of use cases, then please propose. Yet, from my point of view, this is an edge case, closely tied to use cases (e.g. |
It's absolutely not an edge case, seeing how many languages (Python, Rust, C#, C++17, Haskell...) implement it as default. It comes in handy whenever you want the user to be able to provide a path that's either relative (to CWD or another directory, e.g. an include path) or absolute in an intuitive way, which is often in my experience. |
How is
|
Oh hey, there's a |
@obskyr if you could actually provide a usecase for which |
@RX14 Sure - whenever you want a relative path if possible. Off the top of my head, this can occur in two main categories of cases:
In my particular use case that spurred this discussion, I'm generating Makefile dependencies which I'd like to be both readable and reusable on another system. While absolute dependencies (in |
Surely a better fix there would be |
That wouldn't help at all - the entire point is you don't want a relative path if the path you're joining with is absolute. |
Well then you're "stuck" using the 5 line solution @ysbaddaden posted above. It seems a lot nicer than making a complex method to do exactly what you want inside the stdlib. |
Except it isn't complex. Both readable and reusable paths are common use cases, and the path joining behavior is commonly used and easy to understand. The Python stdlib's implementation is 17 lines, and that's with boilerplate and error handling - that's not complex at all. I have to stress, once again: Python, Rust, C#, C++17, and Haskell all do this. It's not complex, it's not uncommon, and its definitely not just "exactly what I want". |
Well, we disagree. We don't want to change the current behavior of I'm probably stupid and confused but your use cases seem like a perfect fit for |
Welp. If I have the time and inclination, I'll put together a proper proposal for a new path joining function, with details on expected behavior and examples where neither |
I don't think it makes sense to change the behaviour of You propose a behaviour similar to calling This can be implemented quite easily by calling components = ["any/path", "/absolute/path"]
components.reduce(".") { |path, component| File.expand_path(component, dir: path) } # => "/absolute/path" |
That's not true -
There seems to be a bit of a misunderstanding - that's not a solution, as that'll always result in an absolute path. Joining |
Well, it does normalize then, doesn't it? Turning a resulting absolute path into a relative one shouldn't be an issue, really. In my above example you can just use a custom, unique path as starting point instead of |
In Crystal 0.24.2,
File.join
doesn't handle absolute paths properly. Take the following example:That expression currently evaluates to
"any/path/absolute/path"
, when the expected value would be"/absolute/path"
.One argument against this is that Ruby's
File.join
also does not handle absolute paths - but every other high-level programming language I've used does (see Python's behavior, for example). Ruby's behaviour here is somewhat infamously cumbersome, so I'm certain it'd be an overall positive change to make.The text was updated successfully, but these errors were encountered: