in reply to Prevent direct acces to object's attributes

This is possible, but you're doing something wrong if you want to do this.

The so-called "inside-out" objects are a solution to this perceived problem, InsideOut is a search that gives you at least Object::InsideOut and Class::InsideOut, and likely many more implementations.

The Cool Train has left inside-out land about two years ago and all the cool kids use Moose nowadays. At least in respect towards interoperability, Moose-based objects are less problematic than inside-out objects.

Why do you want to prevent access to object values using $obj->{...}? Maybe you want to educate your project members to not do that? For example Data::Dumper won't work with inside-out objects...

Replies are listed 'Best First'.
Re^2: Prevent direct acces to object's attributes
by JavaFan (Canon) on Sep 07, 2009 at 18:19 UTC
    At least in respect towards interoperability, Moose-based objects are less problematic than inside-out objects.
    That statement surprises me. Classes implemented as inside out object do not enforce any restrictions on classes that inherit from them, and they can inherit from any class, regardless of how it's implemented.

      Yeah - on second thought the distinction isn't as grave as I made it out to be. In fact, I have used that transparent property of inside-out objects myself to "attach" data to foreign objects that didn't like their data structure modified.

      If an object already is an inside-out object, you have no choice but to continue down that road. The same holds true for Moose-based (hash) objects.

      And in the reverse, if you have a hash-based object, you can glue inside-out extensions to it, and it seems as if you can derive a Moose-based class from it.

        If an object already is an inside-out object, you have no choice but to continue down that road.
        That's not true.
        package InsideOut; use strict; use warnings; use Hash::Util::FieldHash qw[fieldhash]; fieldhash my %name; sub new { my $class = shift; bless do {\my $var}, $class; } sub set_name { my ($self, $name) = @_; $name{$self} = $name; } sub get_name { my ($self) = @_; $name{$self}; } 1; __END__ package Traditional; use strict; use warnings; use InsideOut; our @ISA = qw[InsideOut]; sub new { my $class = shift; bless {}, $class; } sub set_colour { my ($self, $colour) = @_; $self->{colour} = $colour; } sub get_colour { my ($self) = @_; $self->{colour}; } 1; __END__ #!/usr/bin/perl use 5.010; use strict; use warnings; use Traditional; my $obj = Traditional->new; $obj->set_name("NAME"); $obj->set_colour("COLOUR"); say "The name is ", $obj->get_name, " and its colour is ", $obj->get_c +olour; __END__ The name is NAME and its colour is COLOUR
        As you can see, you can inherit from an inside out object, and use tradition hash based objects in the derived class.
Re^2: Prevent direct acces to object's attributes
by vitoco (Hermit) on Sep 07, 2009 at 18:19 UTC
    Why do you want to prevent access to object values using $obj->{...}? Maybe you want to educate your project members to not do that?

    Reading directly from attributes is not a real problem, but writing is, because there are some interdependencies between attributes: some of them are preprocessed values based on other ones (like a cache), and changing them would produce unexpected behavior on some methods.

    Of course, that is mentioned in the POD, but then I thought I missed something from the docs.

    I'm new in writing OO code... Now, Moose and InsideOut objects are in my queue for further reading, just after Damian Conway's book!

    Thanks to everyone...

      You could have a look at the lock functions in Hash::Util. It's a core module since 5.8, so there's probably nothing to install.

      But, I'm sure I've read somewhere that their use is discouraged in objects. Can any Wise Old Monks shed any light on that?

      Just Use Moose. You'll love it.

        You cannot (re)bless a hash that is locked. Which can hinder certain OO programming techniques. Furthermore, locking a hash doesn't prevent accessing the attributes. 'lock_keys' prevents keys to be added 'lock_value' makes values readonly, and 'lock_hash' makes the entire hash readonly. But keys being readonly still makes them readable. And if you have a reference to the hash (which traditional Perl objects give you), nothing stops you from calling any of the unlock function on them.