In Perl, reference to anything is a simple scalar, and has the $
sigil. It's sometimes hard to say what kind of reference it is.
I personally prefix variable names for references with a letter, which indicates ref type. Examples:
my $aValues = []; # arrayref
my $hValue = {}; # hashref
my $oValue = bless {}; # object
my $sValue = \(my $s = 'foo'); # scalarref
...
I've seen both supporters and opponents to such notation. Do you use it? Does it have any disadvantages?
Meh. Arrayrefs and hashrefs and the like don't end up being that confusing around here that the issue comes up for our Perl-data-types very often. (Also: $oValue
? How generic can you be? What sort of an object is it?)
Give me semantic-units Hungarian notation instead: $size_bits
, $size_bytes
, $size_kb
, $size_blocks
, $size_mb
, $size_gb
. The underlying data type? Not as important as adding 3 bytes to 10 megabytes per second and getting 13. That is where Hungarian notation of some form is useful.
Personally I find hungarian notation hard to read. I just use English conventions:
my $values; # is an array
my $value; # is a scalar
my $value_hash; # is a hash
I usually treat objects the same as scalars because how it's used makes it obvious enough that it is an object. However if I ever find a need to I'd use:
my $value_obj; # is an object
If you want statically typed languages, you know where to find them...
But Hungarian notation was never intended to be about technical data types (though it has earned most of its bad rep being misunderstood and -applied for technical data types). The Hungarian who originally invented it (Charles Simonyi) intended it to convey semantic information, e.g. using row
and col
prefixes in code that deals with tables so that you don't mix up row and column indexes.
The purpose of Hungarian notation is to embed semantic annotations that
- cannot otherwise be expressed within the language, especially the type system AND
- are not apparent from the context
in the names of variables. Now, since Perl doesn't have a static type system, it might appear that Hungarian notation should be fairly common. But, take the canonical example for the value of Hungarian notation: tracking the origin of untrusted data.
One of the oft-cited examples for Hungarian notation is to prefix all string variables in an application with either s
or u
(for safe and unsafe), depending on whether the string came from a trusted source (or has been sanitized) or an untrusted one. But: just replace unsafe with tainted and you have a perfect description of tainting in Perl. So, in this case, even though Perl doesn't have a static type system, it has a dynamic type system that allows you to express the semantics of trusted/untrusted within the language and thus Hungarian notation is superfluous. (And even in a language without built-in support for tainting, there are usually much better ways, such as subtyping (Python, Ruby, Smalltalk, ...), annotations/attributes (Java, C#, ...), metadata (Clojure, ...) and static typing (Haskell, ML, ...).)
Also, Perl is pretty darn expressive, and thus it is much easier to keep the entire context for a variable in your head (or within one screenful of code), so, often enough the semantics are apparent from the surrounding code.
Good naming also helps, of course.
Remember: Hungarian notation was invented for C, which isn't expressive and has a static type system whose pretty much only use is as the punchline of a joke.
I don't do this because a reference's usage will make clear its thingy. For example:
$a->{key}; # hash
... if @$b; # array
$c->foo; # object
Choosing names for your variables that communicate what they represent will go a long way. Perl was designed by a linguist and borrows from natural language, so context is key. Our brains are already wired for this sort of processing. Make use of it in how your structure your code!
精彩评论