http://www.perlmonks.org?node_id=646406


in reply to Re: my My $my;
in thread my My $my;

Thanks for the replies, I figured it out now, I think.

Saying

my My $my
indeed tells the compiler that $my should be a My object. This information is not used for type-checking, however (neither at run-time nor at compile time). It is currently only used to make use of the fields pragma, which lets you define your class' fields:
# compile error $my->{no_such_field} ++;
In addition to checking the spelling of field names, you get the improved performance of having the hash access turned into an array/pseudo-hash access (On the other hand, pseudo-hashes seem to be evil, the docs warn about their imminent removal from Perl).
use strict; { package My; use fields qw[ one ]; sub new { return fields::new(shift); } } my My $my = new My; $my->{one}++;
b-deparses to
package My; sub BEGIN { use strict 'refs'; require fields; do { 'fields'->import('one') }; } sub new { use strict 'refs'; return fields::new(shift @_); } package main; use strict 'refs'; {;}; my $my = 'My'->new; ++$$my[1]; ## <--- array access

Replies are listed 'Best First'.
Re^3: my My $my;
by grinder (Bishop) on Oct 22, 2007 at 10:14 UTC
    On the other hand, pseudo-hashes seem to be evil, the docs warn about their imminent removal from Perl

    They have been removed from 5.10. On the other hand, 5.10 adds support for field hashes, which in turn are used for Inside Out objects, which is what all the cool kids are using these days.

    The main thing to remember about field hashes, if you haven't heard about them, is that they allow references to be used as hash keys in an efficient manner. (Yes, there are modules that let you do this already, but the performance stinks).

    • another intruder with the mooring in the heart of the Perl

Re^3: my My $my;
by shmem (Chancellor) on Oct 22, 2007 at 13:59 UTC
    Thanks for sharing that.

    Toying around a bit, I found out that the RHS of my My $my = $foo need not be an object of class My, in fact, it can be any object, or even just a plain array reference:

    package My; use fields qw(bar); sub new { return fields::new(shift) } 1;
    package Foo; use fields qw(foo); sub new { return fields::new(shift) } 1;
    #!/usr/bin/perl use My; use Foo; use strict; my $bar = []; print "\$bar = $bar\n"; my My $my = $bar; $my->{bar} = 'quux'; print "\$my = $my\n"; print "my bar field: $my->{bar}\n"; print "bar: (",@$bar,")\n"; my $foo = Foo->new(); $foo->{foo} = 'is foo'; print "(1)foo: $foo, foo field = ".$foo->{foo},"\n"; my My $bar = $foo; $bar->{bar} = 'is bar'; print "(2) bar: $bar, bar field = ".$bar->{bar},"\n"; print "(3) foo: $foo, foo field = ".$foo->{foo},"\n"; print "(4) foo: $foo, foo field = ".$foo->{bar},"\n"; __END__ $bar = ARRAY(0x827ac28) $my = ARRAY(0x827ac28) my bar field: quux bar: (quux) (1) foo: Foo=ARRAY(0x827ab44), foo field = is foo (2) bar: Foo=ARRAY(0x827ab44), bar field = is bar (3) foo: Foo=ARRAY(0x827ab44), foo field = is bar No such pseudo-hash field "bar" at my.pl line 25.

    Assigning the Foo object $foo to a lexical my My $bar makes it into a My object. Or it seems to do so; the object's body still is an array reference blessed into package Foo, while its fields seem to be of the My package. But then, the 'My' package didnn' import field 'foo'...? Scary stuff, that, great for obfus and to annoy your cow-orkers and maintainers, and for writing hard to spot bugs...

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}