Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re^3: I don't understand UNIVERSAL::DOES()

by chromatic (Archbishop)
on Mar 09, 2007 at 18:48 UTC ( [id://604030]=note: print w/replies, xml ) Need Help??


in reply to Re^2: I don't understand UNIVERSAL::DOES()
in thread I don't understand UNIVERSAL::DOES()

Instead of perpetuating hackish workarounds that take advantage of an implementation quirk that methods are just functions that take an extra parameter, why not fix the real problem and allow methods on all references via autobox?

That's much more in line with how it works in Perl 6. It would be nice to keep the semantics of backported features as similar as possible.

  • Comment on Re^3: I don't understand UNIVERSAL::DOES()

Replies are listed 'Best First'.
Re^4: I don't understand UNIVERSAL::DOES()
by demerphq (Chancellor) on Mar 09, 2007 at 20:57 UTC

    why not fix the real problem and allow methods on all references via autobox?

    Well, that would address /one/ of my concerns, that is it would not just die on an unblessed reference. But it doesnt address the other issues I mentioned.

    UNIVERSAL::DOES() is a perfect opportunity to address a host of typing related issues in Perl in one routine without burdening ourselves with yet another partial solution. Currently we have (at least) ref, Scalar::Util::reftype, Scalar::Util::blessed, UNIVERSAL::isa, overload::Method, and re::is_regexp(). Thats a lot of routines to know about, and to know how to use in concert properly. UNIVERSAL::DOES() seems like the perfect place to roll them all together into something sensible.

    Also it seems to me that DOES is the /correct/ place to ask "can I use $x as a subroutine reference", and not barf because $x is not UNIVERSAL::ISA($x,'CODE') but rather a blessed array reference that happens to overload code deferencing. DOES is about what one can use an object for after all.

    If we can get a sensible routine into core then people will use it, but if its another 2/3rds solution as so many of the existing routines are I bet it wont get used much at all. And will be in my eyes at least a missed opportunity. Especially as by writing it in C the code can be /much/ faster and accurate than any roll your own type detection code is.

    ---
    $world=~s/war/peace/g

      Well, that would address /one/ of my concerns, that is it would not just die on an unblessed reference. But it doesnt address the other issues I mentioned.

      Why not?

      my $regexp = qr/Some Regex/; warn "It's regexpable!" if $regexp->DOES( 'REGEX' ); my $subref = sub { ... }; warn "It's invokable!\n" if $subref->DOES( 'CODE' ); my $overloaded = Way::OverLoaded->new(); warn "It's indexable/keyable/invokable\n" if $overloaded->DOES( 'ARRAY +' ) && $overloaded->DOES( 'HASH' + ) && $overloaded->DOES( 'CODE' + );

      Those may not be the best role names, but I hope the idea is clear.

        The regex example just doesnt work. (Did you try it?) It wont work because UNIVERSAL::isa() doesnt know about "regexness", yes you can make sure that your qr// isa Regexp, but thats not a necessary condition to using a blessed qr// construct. Regexness is defined by whether the reference has regexp magic. Its yet another type-like attribute that is orthagonal to the rest. This is why i proposed the syntax I did, 'qr//' will never be a valid class name in perl, so its a perfect way to ask if something truely has a regexp magic.

        The other examples arent that useful because they fall into the same trap that UNIVERSAL::isa() did, that is confusing class names and types. Without recourse to a secondary routine like blessed() you can't distinguish an unblessed true hash reference from a blessed array reference that wants to mess up your code. AND to make things worse being a member of any of these classes does not actually say if your object supports a given dereferencing operation.

        In other words there is a clear difference between asking "does an object do what the class ARRAY does" and "can I dereference an object as an array". They are orthagonal concepts in perl that have no necessary relationship with each other, despite the fact that UNIVERSAL::isa() decided to merge them. (Arguably a design error much akin to ref() returning classnames on blessed objects).

        And again thats why I suggested the overload::Method like syntax for this, it separates out dereferencability from class membership in a way that lets you ask both questions, in a convenient and unambiguous way, so that people can do what they need to do without using a secondary routine. For instance all of your examples here really need to say

        use Scalar::Util; if (blessed($overloaded) && $overloaded->DOES( ... )) { ... }
        If that guard clause is needed (and it is) then the utility of UNIVERSAL::DOES drops considerably, if not more given that it currently is just a simple wrapper around UNIVERSAL::isa(). Wheras recoded to behave as I've outlined here and it would be able to replace almost every use of reftype(), blessed() and UNIVERSAL::isa() in non-serialisation code out there.

        I really want to see a unification of all the various type-like detection code into one routine and it seems to me that DOES is the best candidate for the job.

        Also, earlier in this thread you made a comment about ignoring various quirks of Perls design and pretending that we are working with something cleaner. In my opinion that approach doesnt lead to useful advances in the state of the art and in fact just leads to oversights. Like the fact that UNIVERSAL::DOES is currently useless unless complemented by the use of Scalar::Util::blessed(), which is hardly an advance over UNIVERSAL::isa(), more like a step backwards if anything. If you can swallow the fact that Perl isnt as clean as you want we can get a truely useful UNIVERSAL::DOES that scratches what I know to be some of your itches, and scratch the itches I have too, and finally introduce a type introspection tool that doesnt need helper routines from disparate modules spread throughout the core. Now that would be progress.

        ---
        $world=~s/war/peace/g

      UNIVERSAL::DOES() seems like the perfect place to roll them all together into something sensible.

      Do you really expect us to say UNIVERSAL::DOES everwhere?

      Do you plan to allow the export of DOES despite the many places where UNIVERSAL claims it's a mistake to have import at all?

      What if there's a package wants to use the DOES function *and* override DOES?

      Wouldn't it be better if your function was called does. If the argument is a class or an object, it would call the DOES method to permit overrides and roles.

        *isa= \&UNIVERSAL::isa;

        works great for me. I don't even have to "use UNIVERSAL" for this. There being no UNIVERSAL->import() makes some sense to me, but, as noted in Universally unimportant and overused, UNIVERSAL->import() appears to exist (and causes problems).

        Defining a special UNIVERSAL::isa() that can detect when it has been misused would be an acceptable compromise to me.

        - tye        

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://604030]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2024-04-26 02:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found