
budman
User
Mar 30, 2012, 5:09 PM
Post #21 of 32
(7751 views)
|
|
Re: [ChopperCharles] private and protected methods
[In reply to]
|
Can't Post
|
|
I think your on the right track. Storing data in hashes is quite easy. What's happens in the class, should stay in the class. Especially when it comes to data. This way in the future you can make changes to the base class, and not have to worry about fixing subclasses as long as you keep the accessors the same. If you need to freeze and thaw the object, for faster load times, look into the storable module to help with that. I played around with Moose to show how it would look (similar to Perl 6).
package fooBar; use Modern::Perl; use Moose; my $m_LastError = ''; after 'new' => sub { say "created instance from ".__PACKAGE__ }; has iAmFooBar => ( isa => 'Str', is => 'ro', lazy => 1, default => sub { run("fooBar") }, ); has lastError => ( isa => 'Str', is => 'rw', default => '', ); around lastError => sub { my $orig = shift; my $self = shift; return blessed $self ? $self->$orig(@_) : $m_LastError ; }; has priv_attrib => ( isa => 'Int', is => 'ro', writer => 'private_set_attrib', default => sub { shift->default_value } ); has run => (is => 'rw'); around 'run' => sub { my $orig = shift; my $self = shift; return blessed $self ? $self->__foo(@_) : __foo($self,@_); }; sub isa_friend { my $class = shift; my $this = shift; if ( blessed $this ) { unless ( $class->isa( ref($this) ) ) { $this->lastError("Access to private method denied."); return 0; } } return 1; } sub default_value { return 0 } sub __foo { my $this = shift; # private access only my $class = (caller)[0]; return -1 unless isa_friend( $class, $this); my $name = blessed $this ? shift : $this; print "Hello $name\n"; my $error_occurred = 0; # to test modular code if ( ! blessed $this && $error_occurred != 0 ) { $m_LastError = "some error"; return $error_occurred; } else { $m_LastError = "" } return 0; } 1;
package TacoBell; use Modern::Perl; use Moose; extends 'fooBar'; after 'new' => sub { say "we can add stuff in ".__PACKAGE__ }; has burrito => ( is => 'ro', isa => 'Str', default => sub { my $self = shift; my $retcode = $self->__foo("Burrito!"); $self->lastError("problem with burrito") if $retcode; return $retcode; }, lazy => 1, ); 1;
#!/usr/bin/perl use Modern::Perl; use TacoBell; my $tb = TacoBell->new(); say "private var is ".$tb->priv_attrib(); $tb->private_set_attrib(55); say "private var is now ".$tb->priv_attrib(); # cause read-only error #$tb->priv_attrib(10); say "\ntb->Burrito:"; my $retcode = $tb->burrito(); say "RC: $retcode ", $tb->lastError(); say "\ntb->iAmFooBar:"; $retcode = $tb->iAmFooBar(); say "RC: $retcode ", $tb->lastError(); say "\ntb->__foo test"; $retcode = $tb->__foo("test"); say "RC: $retcode ", $tb->lastError(); say "\nFooBar:"; my $fb = fooBar->new(); say "\nfb->iAmFooBar:"; $retcode = $fb->iAmFooBar(); say "RC: $retcode ", $fb->lastError(); say "\nfb->__foo test"; $retcode = $fb->__foo("test"); say "RC: $retcode ", $fb->lastError(); # don't do this :) #say "\nModular test for __foo test"; #$retcode = fooBar::__foo("test"); #say "RC: $retcode ", fooBar::lastError(); output:
created instance from fooBar we can add stuff in TacoBell private var is 0 private var is now 55 tb->Burrito: Hello Burrito! RC: 0 tb->iAmFooBar: Hello fooBar RC: 0 tb->__foo test RC: -1 Access to private method denied. FooBar: created instance from fooBar fb->iAmFooBar: Hello fooBar RC: 0 fb->__foo test RC: -1 Access to private method denied.
(This post was edited by budman on Mar 30, 2012, 5:15 PM)
|