Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

You don't seem to really want "inside-out" objects -- you seem to want encapsulated objects. Inside-out is just one way of doing that and it seems like you're going out of your way to try to make it act like something else.

A couple quick observations:

  • Is there exta overhead for overloading?

  • What if Foo or Bar want to overload "%{}" themselves?

  • You give up compile time typo protection. e.g. $self->{ sercet }

I'll let you know if more things occur to me later.


The more I think about it, the more this just seems like a way of disguising an accessor call by way of overloading.

And there's no reason the trick requires inside-out objects. Here's a plain-old blessed hash version -- and it still gives you package-specific hash values that don't collide:

package SmartHash; use strict; use warnings; use Carp; use overload "%{}" => sub { my $caller = caller; croak "Illegal object access" unless $caller->isa(__PACKAGE__) +; return shift if $caller eq __PACKAGE__; return shift->{$caller} ||= {}; }, fallback => 1; 1;

package Foo; use strict; use warnings; use base 'SmartHash'; sub new { my $class = shift; bless {}, $class; } sub foo { my $self = shift; $self->{foo} = shift if @_; return $self->{foo}; } 1;

package Bar; use strict; use warnings; use base 'Foo'; sub bar { my $self = shift; $self->{bar} = shift if @_; return $self->{bar}; } sub foo { my $self = shift; $self->{foo} = shift if @_; return $self->{foo}; } 1;


use strict; use warnings; use Test::More tests => 9; use Test::Exception; require_ok( 'Bar' ); require_ok( 'Foo' ); my $o = Bar->new; my $p = Foo->new; dies_ok { $o->{bar} = 42 } "dies on direct access"; $o->bar(13); is( $o->bar, 13, "Bar obj set/get bar" ); $o->foo(42); is( $o->foo, 42, "Bar obj set/get Bar's foo" ); $o->Foo::foo(23); is( $o->Foo::foo, 23, "Bar obj set/get Foo's foo" ); $p->foo(99); is( $p->foo, 99, "Foo obj set/get foo"); is( $o->foo, 42, "Bar obj's foo is still Bar obj's foo" ); is( $o->Foo::foo, 23, "Bar obj's Foo's foo is still Bar obj's Foo's fo +o" );

prove -v testbar.t

testfoo....1..9 ok 1 - require Bar; ok 2 - require Foo; ok 3 - dies on direct access ok 4 - Bar obj set/get bar ok 5 - Bar obj set/get Bar's foo ok 6 - Bar obj set/get Foo's foo ok 7 - Foo obj set/get foo ok 8 - Bar obj's foo is still Bar obj's foo ok 9 - Bar obj's Foo's foo is still Bar obj's Foo's foo ok All tests successful. Files=1, Tests=9, 0 wallclock secs ( 0.00 cusr + 0.00 csys = 0.00 C +PU)

I guess I'm not clear on what you find so difficult about inside-out objects (assuming a sane inside-out class generator to handle destruction, serialization, threads, etc.). Is "$foo{ id $self }" so much more difficult than "$self->{foo}"? Or even "$self->foo()"?

What are you trying to optimize for? The hash-based interface does avoid having to pre-declare any properties -- you can just say "$self->{baz}" and the "baz" property springs into existence. That comes at the cost of the typo checking.

I can also see a use for it if you're trying to upgrade legacy code. You can just drop "use base 'Encapsulate'" into your object modules and they should continue working like normal without having to edit anything else there, but everything else external that accesses objects will break.

But just as is, this feels close to an XY Problem to me.


Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

In reply to Re: Better Inside-Out Objects :) by xdg
in thread Better Inside-Out Objects :) by Ovid

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others perusing the Monastery: (5)
    As of 2020-02-26 05:15 GMT
    Find Nodes?
      Voting Booth?
      What numbers are you going to focus on primarily in 2020?

      Results (113 votes). Check out past polls.