-
-
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
Implement Path type #5635
Implement Path type #5635
Conversation
@@ -537,16 +537,16 @@ describe "File" do | |||
end | |||
|
|||
it "expand_path for commoms unix path give a full path" do | |||
File.expand_path("/tmp/").should eq("/tmp") | |||
File.expand_path("/tmp/").should eq("/tmp/") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Surely all the specs on file
that deal with pure paths should be moved to path_spec
. We needn't spec the Path
wrapper and Path
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to leave it in until it gets completely replaced. This way it's easy to see that the behaviour is mostly the same except for a few details.
end | ||
end | ||
|
||
# Returns the root path component of this path or `nil` if it is not rooted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the usecase for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not entirely sure myself. But both Java and Python API's have this, so I'd guess it's probably useful for something... internally it's used by #anchor
.
5297198
to
3a9e01b
Compare
Something is really strange with the compiler specs using The With 5ff295d I tried to replace assert_macro "x", %({{x.inputs}}), [ProcNotation.new([Crystal::Path.new("SomeType")] of ASTNode, Crystal::Path.new("SomeResult"))] of ASTNode, "[SomeType]" This line produces a syntax error: Previously it worked with |
That's an array of procs. Problem is, if you write
then compiler will think Solution: use parentheses:
|
But why is this an issue? The change just replaces |
I'd suggest changing name to |
Pathname is just ugly... And its longer for what is hopefully a very well used class. |
We just need not to The language is ugly regarding types, there are no nice "imports" and no way to prevent types leaking all over the global namespace. We just have to accept that and move on. |
@asterite I think it's ok to |
@bew problem is, Path will be required by prelude (it's used in File, which is required by prelude), so including Crystal will create a conflict with Path. |
Can't we just put the specs in |
I still don't understand why the parsing changes based on the addition of a qualifying name space. You can have imports using I'm fine with putting the specs in a module. |
5ff295d
to
e860911
Compare
Now I don't think the parsing changes or has anything to do with what I said above. I'll checkout this branch and investigate. |
e860911
to
b6bfcab
Compare
Found it. If you do: foo([] of T, Y.new) it parses "well" ( However, with: foo([] of T, X::Y.new) the compiler fails to see this, because of the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is pretty good on the API design side. I have lots of comments on the implementation but i'd rather @asterite, @ysbaddaden etc weighed in on the API first.
Would be good to get some more design opinions on this PR from the core team. I'm not fond of putting so much behaviour on the |
The more types we add to the std that's loaded by default (and |
The obvious response to that is that path operations tend to be composed quite often, and providing a path type makes composing these operations a lot easier because you don't have to specify I'm not particularly sympathetic to the compile time argument - I think that Things like deque and set belong in the corelib less than path, but they're required by other parts of the corelib. |
Having to type less is never a good argument in my opinion (or at least I also thought like that, but not anymore)
|
No, having to type less is never a good reason to sacrifice readability or understandability (i.e. adding too much magic), but here we do neither. The only thing we sacrifice for having to type less is adding a new class to the stdlib. Considering the current
will be written in C, rust (unlikely), not crystal. It's a GC'ed language itself - it's not suited for writing a GC.
fair enough, although I feel a lot of the higher-level concurrency abstractions can be in the stdlib not the corelib
That's more code, but not really a whole new class. If the code is only string ops and maths, then it will not be instantiated more than once, and will contribute much less to compile times.
I don't think this is a good idea, writing lightweight parsers by hand is super easy in crystal, usually more robust, and generate better errors. |
Go's GC is written in Go ;-) |
Go also doesn't have numerous places where hidden allocations occur. Even ones you wouldn't think about like |
Can we please keep this thread clear of discussions about GC implementations and other Stdlib features? The gist is: this adds an additional type to corelib. We're also pretty sure that there will be no or only very few additions to that in the future. Having the class makes many things easier to write, but on the other hand adds an additional type to the inference algorithm for every program. @RX14 I agree that having the behaviour defined on the enum is not great. It can easily be moved to private methods on |
There should be no breaking changes here so this should be fine for 0.27.1 |
There is technically a minor breaking change in |
@bcardiff this is still blocking a lot of Windows specs, i'd love it reviewed and merged in the next 2 weeks so I can resume working on Windows over Christmas. |
Any chance this PR will make it into 0.27.1? |
58476bf
to
43747c0
Compare
No, there are breaking changes to |
@straight-shoota Thank you. |
43747c0
to
66c2ab3
Compare
Thanks, @r00ster91. Fixed typos and rebased on master. |
This introduces a new Path type representing a filesystem path.
66c2ab3
to
3869d87
Compare
ord = @name.compare(other.@name, case_insensitive: windows?) | ||
return ord if ord != 0 | ||
|
||
@kind <=> other.@kind |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find this strange, but we can probably fix it later. Why a POSIX path is less than a WINDOWS path?
(and if that makes sense... shouldn't it be the other way around? 😛)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also the PartialComparable is no longer needed due to latest changes in Comparable. But that can be changed later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, you are right! I can fix that in a PR after this one was merged (also removing PartialComparable
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removing deprecating 🙈
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, though it isn't used anywhere else according to GitHub: https://github.com/search?q=language%3Acrystal+PartialComparable&type=Code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the original question: Two paths shouldn't be treated as equal if they are of different kinds, because that means different semantics. They shouldn't compare equal either, so this seems like a legitimate solution.
Could alternatively return nil
of course when comparing different path types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning nil sounds good to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's do this! Thank you everyone for the incredible commitment and patience on this one! 🙇
Yeah, can't believe i's been over a year... 🤣 |
This is a prototype of a Path type encapsulating filesystem paths to have a basis for further discussion in #5550
For now I have only refactored
HTTP::StaticFileHandler
to use the Path type to see how it can be used.