Or perhaps $self->input_line_number(1+$self->input_line_number);. But, recall that the ++ syntax is beloved by millions and for a reason! It is quite a bit out of the way to not be able to manipulate things in-place.
I've made that same observation here several times, and it is one of the reasons that underlies my earlier response on a similar topic. In particular, the last couple of paragraphs.
The oft noted problem with lvalue setters is that, as implemented in Perl 5, you cannot validate the value assigned. But, this is only really a problem if you have public setters for attributes, where you do not have control over the code that will do the assignment.
As previously discussed, I don't allow public accessors. Which means that any values that get assigned to attributes come into the object as (or are derived from) the arguments to public methods where I have the opportunity to validate them before setting them into the attributes. This means I do not have to waste cycles by having the setters validate the values every time they are set.
External values are only validated as they transition the public/private boundaries. Internal code that modifies attributes is under my control, and can be validated by testing during development thereby avoiding the overhead of continual revalidation during production runtime.
Of course, once you do away with the need for runtime validation of individual attributes, then the need(*) for internal use accessors disappears also, which leaves you directly accessing the attributes internally and doing away with another layer of subroutine call and so benefiting performance even further.
(*)Of course, some will argue that you should use accessors rather than direct access internally anyway. Because, they will suggest, this allows you to isolate the internal code from future changes in the structure of the attributes.
I believe this to be a justifiction. Here's why. Let's say you have a piece of code in a method that does:
class Xyz; attribute x; attribute size; someMethod( arg, ... ) { ... assert( arg > x && arg < y ); ... x = ( x * arg ) % size; ... }
With internal accessors you might, at not inconsiderable cost, write that as:
class Xyz; attribute x; attribute size; someMethod( arg, ... ) { ... assert( arg > x && arg < y ); ... self->set_x( ( self->get_x() * arg ) % self->get_size() ); ... }
But the question is, what does that buy you that is worth the cost? In what way could x change in the future such that the change to x would not require the code that uses x to be modified also?
In (most) other languages, the math would also still work. And for those where it wouldn't--for example languages that use different operators for int and float--then again, you'd have to modify the code also.
In perl, same thing. Perl would take care of the conversions.
In other languages, you wouldn't perform math on a string. So either the type wouldn't change, or the code would have to.
I've still yet to see a good example of a case where using internal accessors. allows the nature of the attribute to change, without also requiring change to the code that uses them?
In reply to Re: Some thoughts on Moose Attributes
by BrowserUk
in thread Some thoughts on Moose Attributes
by John M. Dlugosz
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |