-
Notifications
You must be signed in to change notification settings - Fork 48
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
Using Scalar::Util::reftype instead of just ref(), but mindful this time about definedness to avoid warnings #140
Conversation
…ime about definedness to avoid warnings
I don't really like this change. I don't think it should be poking into the internals of objects. |
How do you see it |
It seems this is just a variation on what the code is already doing? |
@jackdeguest the initial version of this triggered warnings when it got into the wild. Would you be able to take a quick look at the test coverage and see if we can improve it before releasing this? There may be some easy wins there and we'd be able to release with more confidence. https://app.codecov.io/gh/libwww-perl/URI/blob/master/lib%2FURI%2F_query.pm |
Thank you Olaf. Sorry I am a bit puzzled, because the code you reference is not my version, but the version before my change, or did I miss something? |
@jackdeguest I believe the coverage will not have changed in your branch. Or it will not have gone up, since there are no tests added, so that seemed safe to reference. I'm not sure why coverage reports are not being created here. Might be an issue with GitHub secrets on PRs from outside of the org. |
Ok, then I propose to add some tests also using array objects, since this is the purpose of this change. Would that be satisfactory? |
That sounds good. Can we do this without adding new dependencies? |
Of course |
I have added tests in files |
Previously, if given an object, it would not try to dereference. The inside of an object is supposed to be an internal implementation detail which you aren't meant to look inside. With this check, objects are handled differently depending on what their internal implementation is.
The current code will reject handling an object at all, treating it the same as a string. Consider an object that implements string overloading and is intended to be used that way. |
So, I think what you're saying is that someone could provide an object which is a blessed arrayref, but that it would be incorrect to make a blanket assumption that dereferencing the array would yield what we expect, because we'd be making an assumption about how the internals of the object are stored. Looking at the docs for
So, previously with a blessed array, we never would have tried to turn treat it as an array, but would have tried to stringify it, which would work in cases where stringification was overloaded. (Edited my initial comment as I realized I hadn't fully grasped the issue in my first pass). |
Would it then be satisfactory if we checked if said array object has stringification and then pass it through ? |
I think a stringification check would make sense if it's an object. That way we don't care what the underlying representation of the object is. If we could refactor that check into a function then that might reduce the size of the diff for this change. |
Done :) Kindly please check the proposed change I have pushed. |
( Scalar::Util::reftype($_[0]) || '' ) eq "ARRAY" && | ||
!( | ||
Scalar::Util::blessed( $_[0] ) && | ||
overload::Method( $_[0], '""' ) |
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.
As far as I can tell, the tests never get to a scenario where overload::Method( $_[0], '""' )
returns true
. It would be helpful to allow for that case as well.
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.
Thanks, @jackdeguest!
Thanks @jackdeguest! Merged at the command line via 85c5a5c |
I have been careful this time to check for variable defined-ness before using
Scalar::Util::reftype
and also sinceScalar::Util::reftype
returnsundef
when false, I made sure to use an empty string by default in equality checks, such as(Scalar::Util::reftype($r) || '') eq 'ARRAY'
I have performed all the test units and all went well.
The advantage of using
Scalar::Util::reftype
over justref
is when one is using array objects. Using justref
would return the object class whereas usingScalar::util::reftype
returns the type as expected, and works for regular arrays as well as array objects.