Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Comment on

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

Indeed. One way to avoid this is to make the methods available for just the attributes we have:

package Person; { my @attributes = (qw/NAME AGE/); sub new { my $type = shift; my $class = ref($type) || $type; my %self = map { $_ => undef } @attributes; my $access = sub { my ($name, $arg) = @_; use Carp; croak "Method '$name' unknown for class Person" unless exists $self{$name}; $arg and $self{$name} = $arg; $self{$name}; }; #### convenience methods are denined here... for my $method ( keys %self ) { no strict 'refs'; *$method = sub { my $self = shift; $access->( $method, @_ ); }; } bless $access, $class; return $access; } } sub salute { my $self = shift; print "Hello, I'm ", $self->NAME, " and I'm ", $self->AGE, "!\n"; }

This will make it enough. We make a lexical of the attributes we need, then wrap it inside the constructor (the closure) so it's remembered when it goes out of scope. We also create setters/getters on the flight, a beautiful ability if not abused.

We also make a nifty trick I learned from Master Damian Conway, by making it lexical, the rest of the class methods (salute(), but actually all of them defined outside the constructor) must use the setter/getters (or the interface) defined inside the lexical scope. Effectively, there's no way for salute() to access the state of the object but by asking it through the methods available.

Let's put this to work:

package main; my $person = new Person; # nice interface $person->NAME( 'John Doe' ); $person->AGE( 23 ); $person->salute; # this also works, of course $person->('AGE', 24); $person->salute; # this doesn't $person->('TOES', 12);

The output from this is, as expected:

Hello, I'm John Doe and I'm 23! Hello, I'm John Doe and I'm 24! Method 'TOES' unknown for class Person at line 59

The initialization and setters worked OK, and then salute() worked as expected. When we tried to trick the object with another method, by adding to the supposed table of methods, it didn't work, because we explicitely know which attributes we manage (in the normal approach, you can never know). This approach makes lifes easier to maintain (just add a new attribute to the array!) and allows us to be very paranoid about access... and by being a lexical, only the code inside the scope of @attributes can change it, but it never does, and so you cannot trick the object. Of course, there's always a way, you can work on perl guts and add a new attribute to the *attributes table, maybe.

Anyway the example was a nice one, point well taken.


our $Perl6 is Fantastic;

In reply to Re: Re: Objects with Private Variables by Excalibor
in thread Objects with Private Variables by btrott

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!
  • 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
  • Outside of code tags, you may need to use entities for some characters:
            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 surveying the Monastery: (9)
    As of 2014-11-20 21:23 GMT
    Find Nodes?
      Voting Booth?

      My preferred Perl binaries come from:

      Results (101 votes), past polls