in reply to Is "ref $date eq 'ARRAY'" wrong?
I am not sure i agree with the comment about not using the value of ref().
Granted there are many issues and complexities to the current implementation of references that make me cringe at times. But given that currently there are more than one "type" of reference available (blessed objects aside for a moment), I see ref() as a reasonable way to query that type (albeit somewhat ugly). Of course its use should be highly restricted and very well documented.
Since Perl does not (yet) perform automatic dereferencing (like say Javascript which handles all the "is it a value, is it a ref" stuff for you). And the accessing of hash and array elements are done with different brackets (again, JS allows both to be accessed with the same square bracket syntax). I think that sometimes just knowing a variable is a reference is not enough.
Now, as for usage, my feeling is that ref() should really only be used for checking subroutine arguments. This should always be very well documented, so that its obvious to the user of your module when and where they are allowed to use references. For instance I have a Collection class, which aims to provide a more OO array-like interface (sort of like the Java and Smalltalk collection classes). It can take either an plain perl array or an array reference. The array reference is more efficient (especially when that is what you have already) since it spares the overhead of passing several arguments and the creation of a new array to hold them. I avoid the problem brought up by Ovid (where the first element of a list is itself an array reference) by only allowing a single array reference to be passed:
if (scalar @args == 1) { # .. got an array ref } else { # treat it as a plain array }
I also do the same for my Dictionary class (a hash wrapper) with hash refs and hashes in the argument list.
All other usages of ref() are suspect, but as always if you can justify your reasoning in a good comment, and make sure that you are not causing more problems than you are solving, by all means use it.
All that ref() stuff said, I highly disagree with that usage of UNIVERSAL::isa.
UNIVERSAL is Perl's attempt at a base object class, which like references is maybe not so good an implementation of it. But one of the fundemental base concepts of OO is that of encapsulation, and that usage (and the importation of isa as suggested in the documentation) violates that concept totally.
As for all the thoughts about accepting other types of classes (some which might overload @{} or something similar), this should be detailed in the documentation, and handled approriately. Something like this could be possible.
if (ref($date) =~ /^ARRAY$/) { # ... its an array ref } elsif (ref($date) =~ /ARRAY/) { # ... its an array based class } elsif (overload::Overloaded($date)) { # ... although not definitive, # its possible that @{} is overloaded # use this at your own risk } else { # its probably a string .... }
Of course, I cannot stress documentation enough, it will clear up all the ambiguities of usage.
-stvn
|
|---|