Commonly, you see the admonition not to operate on the members of an object, but only to work through methods. So you end up with the klunky get-change-set routine. Such primitive, 20th-century tools.

The thing is, if you have advertized that you can put a scalar in and retrieve the same scalar, you've just set in stone that, fundamentally, you've got a scalar variable. Go ahead and make it one, and let the user treat it like one. Same for an array or even a hash. If it's a settable-gettable, it's a variable and should be advertized as one.

Here's the magic in the meditation: if it's not an ordinary version of whatever data type, you can tie — and thus encapsulate — it. (Update:) This is not to say that it's always the Right Thing To Do. If you need validation performed for each store, you would have to have a separate flag to indicate error, and it would be cumbersome for the programmer. But for values that the user is free to manipulate (and especially for those that he will often update), it can be a significant improvement in convenience.

Here's some silly code to illustrate. The "password" is stored in an encrypted form in memory (presumably as a cartoonishly misguided attempt to be more secure).

package Password; use Carp; use strict; my $security = 'reallysecure'; sub TIESCALAR { my $class = shift; my $arg; return bless \$arg, $class; } sub FETCH { my $self = shift; confess "wrong type" unless ref $self; croak "usage error" if @_; return substr($$self ^ $security, 0, length($$self)); } sub STORE { my $self = shift; confess "wrong type" unless ref $self; my $newval = shift; croak "usage error" if @_; if (length($newval) < 5) { carp "Not long enough" } elsif (length($newval) > 12) { carp "Too long" } else { $$self = substr($newval ^ $security, 0, length($newval)); # print "Stored ", join('.', unpack('H2'x length($$self), $$self)), + "\n"; # print "Plain is ", join('.', unpack('H2'x length($$self), $newval +)), "\n"; } } sub encoded_form { my $self = shift; $$self; } package Main; my $foo; # This would be my object my $pwref = tie $foo->{'bar'}, 'Password'; $foo->{'bar'} = 'squamous'; print $foo->{'bar'}, "\n"; $foo->{'bar'} =~ s/am/a1m/; print $foo->{'bar'}, "\n"; print "Encoded form is ", $pwref->encoded_form, "\n";

We're not really tightening our belts, it just feels that way because we're getting fatter.

In reply to Encapsulation without methods by Roy Johnson

Title:
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, details, 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, summary, 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.