-
-
Save draegtun/1782691 to your computer and use it in GitHub Desktop.
{ | |
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' |
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
There are some Perl modules already on CPAN which do provide lvalue accessors.....
- https://metacpan.org/module/Object::Accessor
- https://metacpan.org/module/Class::Accessor::Lvalue
- https://metacpan.org/module/Object::props
- https://metacpan.org/module/methods
I've never tried any of these so YMMV.
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:
To get the...
... 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