-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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 unwrap function to allow wrapper types to avoid over-overloading convert #32613
Conversation
base/essentials.jl
Outdated
|
||
function convert(::Type{T}, x) where {T} | ||
y = unwrap(x) | ||
return y === x ? x : convert(T, y) |
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.
MethodError if y === x
?
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.
Yeah, I wasn't quite sure on how this should interact (replace?) convert(Any, x)
, so I just simulated convert to Any
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.
But convert(T, x)
is supposed to return something of type T
. Returning x
works for Any
but not all T
.
Just a report of possible consequence of not having this (this is on Windows, Julia 1.1, on Linux and OSx the problem does not seem to be that big - which is surprising):
CC @nalimilan |
The same timings for Linux:
|
…ase.unwrap and tests
Alright, added the MethodError, docs for |
""" | ||
Base.unwrap(x) | ||
|
||
Lower, or "unwrap" a value that has Base-defined representation. Currently |
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 do "lower" and "Base-defined" mean exactly?
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.
Base-defined really means that you convert/transform your wrapper type to a value with a type that already has a convert(T, x)
definition, which for the most part, will be Base/stdlib-defined 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.
OK. That doesn't sound very explicit to me, and if that's only try "for the most part" it shouldn't be presented as a general property. Why not just say "unwrap"?
wrapperstruct = WrapperStruct("hey") | ||
@test_throws MethodError convert(String, wrapperstruct) | ||
Base.unwrap(x::WrapperStruct) = x.x | ||
@test convert(String, wrapperstruct) == "hey" |
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 test that it works when the destination type differs from typeof(unwrap(wrapperstruct))
? E.g. with Int
and Float64
.
@JeffBezanson, this is ready for another review when you have a moment. |
Do we really need this? I just retested queryverse/DataValues.jl#52, which simply removes that offending I'm not keen of thinking of |
No, this isn't meant as a generic "wrapper" API or anything; |
In that case, why not use a less "good" name now and preserve |
I don't think we're going with this approach, as it's a bit of a hack anyway. I'm beginning to believe that might not be reasonable for |
Would allow packages like CategoricalArrays and DataValues to avoid having to overload
convert(::Type{Any}, x)
with their own definitions (due to wanting genericconvert(::Type{T}, x::MyType)
definitions). Just putting this up as a POC to get feedback.Ref: JuliaData/CategoricalArrays.jl#177, queryverse/DataValues.jl#51