-
-
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
Calling an NamedTuple#to_h on an empty now has meaningful error message #4076
Calling an NamedTuple#to_h on an empty now has meaningful error message #4076
Conversation
@karlseguin do you have any scenario for this? I am not convinced the Tuple does not have a Another alternative could be to do something as follows. Depending on your use case it might be useful or not. def some_key?(**opt)
if opt.empty?
:empty
else
opt.each do
return opt.keys[0]
end
end
end
some_key? foo: 1 # => :foo
some_key? # => :empty |
I'm sure I could come up with a different (better) way to solve my specific problem. But it seems weird to me that calling a method on an instance would give a compiler error based on the state of that instance. On the other hand, I guess the fact the they're known at compile time means that we can do the check at compile time. I definitely think the current behavior is wrong (if for no other reason as being an unhelpful error message), so, we could: 1 - Change the default type to something else, but what? My case was factories for creating tests objects that looked like:
the simplest solution in this case would be to make it nullable. |
For reference, this is how it's currently being handled
|
Why not make it return nil. Because this is done via macros, I don't think that you will actually have to deal with |
I changed it to give a more meaningful compile-time error. This seems like the least risky improvement. I couldn't figure out how to get it under test though. |
👍 for returning Otherwise scenario below becomes impossible: def foo(**options)
options.to_h
end |
to_h returns hash, not nil. Original PR was OK |
I still think that raising in compile time is the right thing to do. Dealing with a hash version of a named tuple is far from a type safe thing. def foo(**options)
# use options.to_h
end there should be some basic assumptions of the types of the values. for example: all integers def foo(**options)
options.to_h.values.sum
end So What happens if we want to return a hash (of some type) for the empty tuple? So, in the sample case of returning the sum of the values of the named tuple the programer is left with two options. a) overload: def foo
0
end
def foo(**options)
options.to_h.values.sum
end b) split the case with and weird def foo(**options)
if options.is_a?(typeof(NamedTuple.new))
0
else
options.to_h.values.sum
end
end |
@karlseguin I authored the changeset, there was an unneeded begin/end block since now there is a macro if. After CI pass this should be ready to merge. I also added a spec for this (yet upon #2391 it could be moved to the std) |
switched from making it return {} => Nil to just improving the compile-time error message