Skip to content

Instantly share code, notes, and snippets.

@draegtun
Created February 9, 2012 20:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save draegtun/1782691 to your computer and use it in GitHub Desktop.
Save draegtun/1782691 to your computer and use it in GitHub Desktop.
Python accessor example converted to Moose
{
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'
@run4flat
Copy link

run4flat commented Feb 9, 2012

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.

@draegtun
Copy link
Author

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

@run4flat
Copy link

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).

@run4flat
Copy link

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

@run4flat
Copy link

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

@draegtun
Copy link
Author

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