People often ask me whether Perl has "real data structures, like C." I am forced to answer the same way that I answer questions about lists of lists: "Well, yes . . . and no." You already know that there are only a few data types in Perl: scalars, arrays, hashes, subroutines, plus a few odds and ends like filehandles. Structures, like those used in C or Pascal, are not among those types. So in one sense, Perl doesn't have structures. But, on the other hand, hashes provide a very similar effect: $student{'last'} = 'Smith'; $student{'first'} = 'John'; $student{'bday'} = '01/08/72'; When referring to an element of a hash, you can omit the quote marks around the key so long as it is a valid Perl identifier: $student{last} = 'Smith'; This looks somewhat like an element of a structure, doesn't it? Your first reaction to this might be something like, "Eww, that's using a string to look up a member of a structure! That's horribly inefficient! A real structure would use some kind of numeric offset computed by the compiler." However, this is wishful thinking where Perl is concerned , and you shouldn't let it bother you at all. [3] Perl is an interpreted language. Accessing variables and elements of arrays and hashes is relatively slow no matter what. The time required to look up an element of a hash is of little consequence in the grand scheme of things.
"Structures" made out of hashes can be passed into subroutines and put to use there: sub student_name { my %student = @_; "$student{first} $student{last}"; } print student_name(%student); Now, this may look useful, but it is not particularly efficient. When you pass a hash as an argument, what you are actually doing is unrolling the hash into a list of elements, then reading those elements back into an entirely new hash inside the subroutine. There are also some syntactic limitations. You can't easily pass two hashes this way:
So, although hashes are the right general idea, they aren't perfect. What works better is using references to hashes and, in particular, using anonymous hash constructors to create them: $student = { last => 'Smith', first => 'John', bday => '01/08/72' }; You also can create an empty structure and fill it in one piece at a time. Using the arrow syntax to access the members of your "structures" makes things look even more like C or C++:
Because you are manipulating scalars, not hashes, passing them into subroutines is more efficient, and passing more than one at a time is no problem: sub roommates { my ($roomie1, $roomie2) = @_; # clever code left as exercise ... } roommates($student1, $student2); This technique is the basis for the way that objects are constructed in most Perl classes. For more about object-oriented Perl, see Item 49. For more ways to use anonymous hashes, see Item 27. |