I've been thinking about those comments overnight, and I don't have any particular objection to them. Certainly not the second one anyway. I think that one could easily fall under the auspices of my statement from the OP:
... used sparingly where they clarify things that the notation ... fails to convey.
That said, context is everything, and your snippet in isolation of the code (and further commenting) around it, makes it hard to decide if these are really warrented or not. For example, here is a possible context for your snippet:
package Junk1;
sub new {
my( $class, $attributes ) = @_;
my $self = bless {}, $class;
# add attributes to object
my @fields = (keys %{ $attributes });
@{ $self }{ @fields } = @{ $attributes }{ @fields }; # hash sli
+ce
return $self;
}
package main;
my $obj1 = Junk1->new( { a=>1 , b=>2, c=>3 } );
And here are 4 more that, in the absence of further information, achieve the same thing. And all of which I think are preferable, and clearer to a lesser or greater extent
This one avoids the hash slice, and the (potentially confusing) intermediate array (called @fields) to hold the names of the keys, that are referred to in the comment as attributes. (Not to be confused attributes of course, which are something quite different!)
And by using %{ $ref } on both sides of the assigment, it makes it clear, even to a beginnner, that we are doing something with hashes:
package Junk2;
sub new {
my( $class, $attributes ) = @_;
my $self = bless {}, $class;
%{ $self } = %{ $attributes };
return $self;
}
package main;
my $obj2 = Junk2->new( { a=>1 , b=>2, c=>3 } );
This takes it a step further and does away with the separate assignment completely. Of course, that may or may not be possible depending upon if and how you choose to validate the arguments to the constructor.
package Junk3;
sub new {
my( $class, $attributes ) = @_;
my $self = bless { %{ $attributes } }, $class;
return $self;
}
package main;
my $obj3 = Junk3->new( { a=>1 , b=>2, c=>3 } );
This one goes a step further, and probably a step too far for safety. It avoids naming the object reference completely, and also avoids copying the data. This latter step is potentially dangerous if you pass anything other than an anonymous hash to the constructor, and I would avoid it for that reason.
package Junk4;
sub new {
my( $class, $attributes ) = @_;
return bless $attributes, $class;
}
my $obj4 = Junk4->new( { a=>1 , b=>2, c=>3 } );
Finally, my preferred option. Pass the arguments as a simple list, accumulate them into a hash when unpacking them from @_, and bless a reference to that as the object:
package Junk5;
sub new {
my( $class, %attributes ) = @_;
return bless \%attributes, $class;
}
my $obj5 = Junk5->new( a=>1 , b=>2, c=>3 );
To my mind this is the clearest, cleanest and most maintianable option and is, perhaps, less likely to confuse a "beginner". As such, I don't see scope for clarification via comments. But that is still making an assumption about the knowledge level of those that will follow, and that's my beef.
The fact that the level of knowledge of the audience is uncertain does not obviate the need to address the audience at a certain level.
But that's the problem. At what level?
The idea that everytime any Perl programmer uses a hash slice, he should annotate that usage with # hash slice, still feels faintly ludicrous to me. Or to quote some of those I found on the net
# Ooooh, hash-slice. :)
# woo, hash slice
# A slice of Hash
# Aren't hash slices lovely?
# Hash ref slice
- But should we also annotate array slices with # array slice?
- How about dereferencing code refs: $code->(); # Call the code?
- Or creating them: thread->new( \&thread ); # pass a reference to the code?
- How about the ternary operator: my $var = $x < 2 ? 2 : $x; # Lower bound for $var is 2?
Where is that line to be drawn?
Would you argue against explanatory subroutine and variable names because a really good programmer doesn't need those hints?
Absolutely not, but the sting in the tail of the question is not the reason. It's because they do not create a maintenance problem. Nothing is duplicated; no couplings are created; they can't lie; they are tested.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
|