public
Created

Python accessor example converted to Moose

  • Download Gist
accessor.pl
Perl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
{
package AnotherPerson;
use Moose;
use namespace::autoclean;
has _firstname => (is => 'rw', isa => 'Str', accessor => 'firstname');
has _lastname => (is => 'rw', isa => 'Str', accessor => 'lastname' );
}
 
my $you = AnotherPerson->new;
$you->firstname('David');
$you->lastname('Mertens');
 
 
 
#
# Stackoverflow answer: http://stackoverflow.com/a/9187853/12195
#
 
__END__
 
# orig Python example
 
class AnotherPerson:
def __init__(self):
self._firstname = None
self._lastname = None
 
@property
def firstname(self):
return self._firstname
 
@firstname.setter
def firstname(self, newname):
self._firstname = newname
 
@property
def lastname(self):
return self._lastname
 
@lastname.setter
def lastname(self, newname):
self._lastname = newname
 
you = AnotherPerson()
you.firstname = 'David' # These two lines call instance methods
you.lastname = 'Mertens'

draegtun, what is the usage of this class? For example, would the firstname and lastname assignments work the same way (with an =), or would it be a method? In other words, would it look like this:

you->firstname = 'David';

or would it look like this:

you->firstname('David');

The first would require some fancy tie magic, while the second is what I would expect.

Apart from showing how this is done in Moose (in comparison to the Python example) I don't think this is of much real use in day2day stuff.

The example just shows you you can define an "internal" attribute with a different setter/getter method. However you can still get to attribute because Moose still boils down to being a hash based OO. For eg. $you->{_firstname}

Remember in Moose getter & setters are just method calls:

$you->firstname('David');      # setter

$you->firstname;               # getter

To get the...

$you->firstname = 'David';

... would require setting the lvalue on the method. Moose doesn't do this. However it hasn't stopped someone adding it has a MooseX extension :) See http://p3rl.org/MooseX::Meta::Attribute::Lvalue

Yes, but now for something on the crazy side. Is there a way to write a Perl method (with or without moose) such that you could say:

$object->name = 'David';

and have it execute a validation method for you? The first thought is, sure, you could do this by returning a tied scalar; then, by overriding the STORE method, you could have validation code. However, what if your attribute is an object? In that case, tying a scalar would solve the assignment issue, but would break standard method chaining like

my $width = $window->page_widget->width;

If the page widget returns a tied scalar, you won't be able to call a method on it because tied scalars do not support method calls. In this case, however, (and this is where I'm stretching it), you could use Damian's Contextual::Return. In lvalue context, return the tied scalar with a validation method. In any other context, return the object (or whatever sort of value that would be appropriate).

No, wait, even better, just use Want: https://metacpan.org/module/Want

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.