-
-
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
Add sub/superset checking methods to Hash #7500
Add sub/superset checking methods to Hash #7500
Conversation
9f035f3
to
79e465b
Compare
Is it GTG / anything else to do here? |
aa4beb4
to
de59f20
Compare
I have some doubts about this change. These methods ( Set relationship methods are also relevant for other collection types besides |
Why are you doubting? ;) These operators are usually overloaded based on the context, thus I see nuffin' wrong in using them according to the most common scenario - they're being overloaded for
They're most needed IMO in places where you'd expect overlapping set of values, but only for types holding distinct value sets, like |
I don't think the usefulness of {sub,super}set is limited to types which exclude duplicate values by design. You might as well use an |
I don't get it, |
|
Yeah, but why would you do that given that there's
I'd say it's pretty weird to use |
A But I don't think this discussion about unrelated details leads us much further. IMHO we simply shouldn't apply different semantics to comparison operators on different collection types. |
We should just assign predicate names |
@straight-shoota I'd like to have ability to use it in specs with |
That's a valid point. But I wouldn't want to risk conflicts in API methods just for improving spec usage. Anyway, I've been thinking about improving the expectations API to allow making a matcher from arbitrary methods, not just comparators. This would be helpful for many other use cases as well. For example |
It seems this is actually pretty easy to implement: require "spec"
module Spec
module ObjectExtensions
def should_be(file = __FILE__, line = __LINE__)
value = yield self
unless value
fail("Assertion failed", file, line)
end
end
end
end
describe Array do
it "is empty" do
a = [1, 2, 3]
a.should_be &.empty?
end
end https://play.crystal-lang.org/#/r/830q I think The only problem I see with this is that it can be confused with Another problem is that we can't print a friendly error message, like "expected to be empty", but I don't think that's a big problem because the line where the error happened is still shown so one can deduce what the failure is. An advantage of using Thoughts? This could also be discussed in a separate issue, but I think this would be fantastic to have. Writing |
I've experimented with that used an expectation type wrapping a proc. It works, but it's not as nice. Didn't figure that the block could just be executed directly and you don't need to worry about proc generics 🤦♂
|
I started writing it like that too, and later realized it could be executed directly! 😅
I'm not sure how, macros don't work as instance methods. Meaning that Well, we could think about what an instance macro is, but it's an entirely different, bigger subject. |
I wanted to implement this but in some spec files we have:
With this new feature it would be written like this:
Shorter, but uglier. Maybe we could name it a.assert &.empty?
File.assert &.exists?(...)
a.assert &.includes?(3)
ch.assert &.closed?
reader.assert &.has_next?
'a'.assert &.lowercase? I think everything reads fine with |
Then also add |
Let's discuss this in a dedicated issue. |
I'd like to revisit this PR, as its main purpose is to add support for the sub/superset checking to Could we settle on some course of action? I see couple of options:
Any thoughts? |
I still wouldn't want to compromise API integrity, so number 3. |
de59f20
to
955fae9
Compare
@straight-shoota I've renamed the methods and now they're 1:1 with the ones found in |
I just realized these methods apply in exactly the opposite direction to what I might expect. These semantics are not new. They are the same as in So maybe we should rather introduce these methods here under a differnt, less ambiguous name. And rename those in |
@straight-shoota Makes sense but I'd start with renaming (and deprecating) methods in |
I've just opened a separate issue for this: #10020 And ideally we'd agree on that, then change this PR + add one for Set. |
955fae9
to
465e548
Compare
398b611
to
5d8c8c6
Compare
Can this get a 2nd approval? |
🏓 /cc @sdogruyol |
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.
Thank you @Sija 🙏
Adds sub/superset checking methods to the
Hash
class (matching the ones inSet
):Hash#subset_of?(other : Hash)
Hash#proper_subset_of?(other : Hash)
Hash#superset_of?(other : Hash)
Hash#proper_superset_of?(other : Hash)