I am trying to understand how lexical_has attributes work in Moops. This function comes from Lexical::Accessor and, as I understand it, the lexical_has function can generate a CODE link to any attribute of a class can "lexically have" it using a scalar link (which is stored in accessor => ). The CODE link can then be used to access the class attribute in a way that is "gaining" volume (because they are "inside out" ??). But these are just my guesses and wild guesses, so I would appreciate a better explanation. I also want to know why this approach does not work in the following example:
Working with an example that is part of Moops Introduction I am creating a class Car :
use Moops; class Car { lexical_has max_speed => ( is => 'rw', isa => Int, default => 90, accessor => \(my $max_speed), lazy => 1, ); has fuel => ( is => 'rw', isa => Int, ); has speed => ( is => 'rw', isa => Int, trigger => method ($new, $old?) { confess "Cannot travel at a speed of $new; too fast" if $new > $self->$max_speed; }, ); method get_top_speed() { return $self->$max_speed; } }
Then I instantiate the object and try to use its methods to access its attributes:
my $solarcharged = Car->new ; # This correctly won't compile due to $max_speed scoping: # say $solarcharged->$max_speed; # This shows expected error "too fast" $solarcharged->speed(140); # This prints nothing - wrong behavior? say $solarcharged->get_top_speed();
The last line using a custom accessory illuminates me: nothing happens. Am I missing an attribute or setting for a class (labeling it or lazy => 0 does not work)? Do I need a BUILD function? Is there an initialization phase that I skip?
NB If I add the setter method to a class that looks like this:
method set_top_speed (Int $num) { $self->$max_speed($num); }
and then call it in my last series of statements:
# shows expected error "too fast" $solarcharged->speed(140); $solarcharged->set_top_speed(100);
The get_top_speed() method starts to return properly. Is this expected? If so, how does the default setting of class parameters work?
I reported this as an error here: https://rt.cpan.org/Public/Bug/Display.html?id=101024 .
Since this can be easily circumvented by using the "perl convention" (ie, not using lexical_has and prefix private attributes with " _ "), and this question arose due to an error, I do not expect a fix or patch as an answer . For generosity - I would appreciate an explanation of how Lexical::Accessor should work; how it "provides" a private internal access area for accessories; and maybe some kind of CS theory about why this is good.