p5pclub / ref-util

Ref::Util - Utility functions for checking references
6 stars 11 forks source link

Ref::Util does not handle magic correctly #22

Closed tonycoz closed 8 years ago

tonycoz commented 8 years ago

$ perl -MRef::Util=is_arrayref -E 'my $x; package Foo { sub TIESCALAR { bless {}, shift } sub FETCH { $x } }; tie $y, "Foo"; $x = []; say is_arrayref($y) ? "YES" : "NO"; say ref $y' NO ARRAY

Adding SvGETMAGIC(ref) before the condition check in FUNC_BODY should fix it

xsawyerx commented 8 years ago

I've been thinking about this a lot. In the above test, $x is an arrayref, but $y isn't. It's a blessed hashref. When you want to use $y, it returns an arrayref instead. This sounds very similar to overload where we say "It isn't, but if you ask for it, it will be". Do we want to support "you can use as"?

(So far I've been against it.)

arc commented 8 years ago

I don't think that applies here, regardless of whether Ref::Util should return true for the "can be used as an X" case: I get the same result if I change the {} in Tony's example to [], thus ensuring that there are no hash refs around to confuse the issue.

Sawyer X notifications@github.com wrote:

I've been thinking about this a lot. In the above test, $x is an arrayref, but $y isn't. It's a blessed hashref. When you want to use $y, it returns an arrayref instead. This sounds very similar to overload where we say "It isn't, but if you ask for it, it will be". Do we want to support "you can use as"?

(So far I've been against it.)

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/p5pclub/ref-util/issues/22#issuecomment-236928130, or mute the thread https://github.com/notifications/unsubscribe-auth/AABa9-AZ_ERb0mgs_khYAhvA4esol4NKks5qb1jFgaJpZM4JD-Gs .

Sent from my phone — please excuse brevity

xsawyerx commented 8 years ago

But that would still mean that if we make this change, it will succeed when it's a hashref, no?

arc commented 8 years ago

I don't think it is a hash ref when the hash is used only to implement the object that it's tied to — tied($y) would be, but that's the only way (other than using XS or Perl's internals) of determining that there's a hash ref anywhere behind $y. You wouldn't be able to use $y as a hash ref, for example.

xsawyerx commented 8 years ago

Alright. Convinced. :)

xsawyerx commented 8 years ago

Fixed. Thank you!