Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

Python accessor example converted to Moose

View accessor.pl
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.

Owner

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

Alright, see this gist: https://gist.github.com/1790290

Owner

There are some Perl modules already on CPAN which do provide lvalue accessors.....

I've never tried any of these so YMMV.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.