Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

Comment on

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

You have explained what he is trying to accomplish, but I actually more was looking to know why he wants to do this. This kind of access control is, in my opinion, a social issue that should not be solved with technology. But since I actually don't know the motivation, I might be wrong on that.

Replace fields with another object system that detect access to a non-declared object variable (run-time or compile-time).

This being perl, there is always a way to access and manipulate object fields no matter what technique you use (yes, even Inside-Out objects can be reached with the right level of black magic). So no matter what features I show you, there is always a way around it for someone who is motivated enough.

Is there an perl object system / framework that supports the above requirements? Moose and Mouse have been considered and fail the last requirement.

Moose has read-only accessors and if you pass unknown attributes to the constructor they will not be added to the underlying object instance. There is also the MooseX::StrictConstructor module which makes passing those unknown attributes an error. Honestly, this, along with some tight type constraints should be enough to validate the data coming from JSON::XS and being passed to the Moose constructor, which seems to be what your goal is.

That all said, none of this will protect the underlying instance structure. But I really think you need to ask yourself, is my environment so hostile that I actually need to protect the instance structure? Can I not enforce things via the accessors and object interface?

Now, if you are really dead set on actually doing this, Moose does provide you the features you need (I suspect Mouse can do this too, but I don't know the actual incantations to do so). So here is the code that you would need in your class BUILD method (or in a common base class if you want, it will still work correctly).

package LockedBox; use Moose; use MooseX::StrictConstructor; use Hash::Util qw[ lock_keys lock_value ]; has bar => ( is => 'ro' ); sub BUILD { my $self = shift; lock_keys( %$self ); foreach my $attr ( $self->meta->get_all_attributes ) { lock_value( %$self, $attr->name ) } }
This basically just locks the instance, then locks each of the values that are defined via Moose. This means that when you create an instance with Moose like so...
my $foo = LockedBox->new( bar => 10 );
You will first get the normal Moose constructor behavior which is to only use the keys that are defined. But since I actually added MooseX::StrictConstructor into this, that means that if you were to do this ...
my $foo = LockedBox->new( bar => 10, baz => 100 );
The code would fail with an exception.

Next, since we locked all the hash keys, if someone were to try and do this ..

$foo->{baz} = 20;
It would die with the error "Attempt to access disallowed key 'baz' in a restricted hash" which is because of Hash::Util::lock_keys.

And lastly, since lock_keys only prevents you from adding new keys but not altering existing ones, we found all the valid keys in Moose and locked those values with Hash::Util::lock_values, which means that this code ...

$foo->{bar} = 20;
Will throw the following error "Modification of a read-only value attempted".

Now, in my opinion, all this is overkill. If the users of your class are violating the encapsulation, then you have a real problem with those users and your documentation should point out such incorrect usage. If these other users are actually co-workers, then you have a social problem on your hands and one that needs to be fixed socially and not technically. In the end, all some jerk needs to do is use Hash::Util to unlock the keys/values and they can get at that, but this really is an explicit violation and should be dealt with.


In reply to Re^3: fields alternative? by stvn
in thread fields alternative? by bannaN

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 monks are getting baked in the sun...

    How do I use this? | Other CB clients
    Other Users?
    Others scrutinizing the Monastery: (6)
    As of 2018-06-18 12:43 GMT
    Find Nodes?
      Voting Booth?
      Should cpanminus be part of the standard Perl release?

      Results (109 votes). Check out past polls.