Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

james (1129)

james
  (email not shown publicly)
http://whoot.org/

...

Journal of james (1129)

Tuesday June 10, 2003
05:38 AM

Magic References

[ #12725 ]

I've been playing around with Perl over the last couple of days to see what I can do with references. I really get annoyed with having to test everything to see if it is blessed before testing to see if it matches the interface that I'm expecting:

    if (blessed( $arg ) && $arg->isa('Some::Class')) {
        # ...
    }

So what I've been trying to do is get it so that references are automagically blessed into a class that shares the name of their reference type:

    % perl -Mmagicrefs -MData::Dumper -e 'print Dumper( {} )'
    $VAR1 = bless( {}, 'HASH' );

And it all works, so now I can do:

    use lib './lib';
    use strict;
    use magicrefs; ## turn on magic references

    my $c = {
              Auto => 'blessed',
              refs => 'are',
              fun => '.'
            };

    print $c->keys->join(','),"\n";

    ## or ##

    if ($c->keys->grep( sub { /^[A-Z]/ } )->size == 1) {
        print "right\n";
    } else {
        print "wrong\n";
    }

    ## or ##

    my %hash = $c->deref;

    ## or with the magic of deparse

    print sub { 1; }->code(), "\n";

I'm guessing the chances of this going into the core are pretty slim however :-)

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • The "blessed( $arg ) && $arg->isa('Some::Class')" idiom is not necessary. You can do

    #!perl -l
    $x = {};
    print UNIVERSAL::isa($x,"Foo::Bar") ? 1 : 0;
    print UNIVERSAL::isa($x,"HASH") ? 1 : 0;
    __END__
    0
    1

    (as documented in the UNIVERSAL manpage)
    • I know, I was using it as a small, trite example. The actual problem is that its easier to refactor away conditions if everything is an object - which is my real dislike. I felt going into why I like to refactor away conditions was probably beyond the scope of the journal entry, which was more about having HASH/ARRAY/SCALAR/... objects, and the nice things that you can do once you have them.
      • And by the way are you going to upload magicrefs to some comprehensive perl archive network ?
        • It's essentially a patch against pp.c in the perl source. I could put it on CPAN, but it seems like a strange place to put a patch. I think it might be possible to do something similar with optimizer.pm, but I need to talk to sky a little about that.
          • Ah. You're evil, then ;-) If this is a core patch, then I don't understand what's in magicrefs.pm -- is it a lexical pragma ? What core function(s) are you patching, and to do what ?
            • magicrefs.pm is a pragma similar to sort, ie, not lexical.

              Essentially it alters S_refto in pp.c. magicrefs.pm sets a hint that is examined in S_refto to determine whether or not we should bless all references that are created (with the exception of those that are SvREADONLY). magicrefs also use's the various reftype modules.

  • Newfangled (Score:3, Informative)

    by acme (189) on 2003.06.10 7:36 (#20964) Homepage Journal
    Now all you need to do is make sure that it works with Acme::Dot and then we have Ruby in Perl!
  • Possible breakage (Score:4, Informative)

    by 2shortplanks (968) on 2003.06.10 8:42 (#20969) Homepage Journal
    Quite a lot of code needs to know if what it's passed is a object (which it shouldn't go inside) or a hash (which it can.) To do this it uses blessed which you've just broken.

    Let's fix that

    sub BasicType::a_sub_not_likely_to_be_here { 0 }
    @HASH::ISA=qw(BasicType);
    @ARRAY::ISA=qw(BasicType);
    ...
    (untested code, of course)