· 9 years ago · Oct 07, 2016, 06:00 PM
1# Perl References
2
3Simple Perl variables are called `scalars`. Examples of scalar values are
4
5```perl
6 $number = 123;
7 $string = "String";
8 $file_handle = open "<filename";
9 $null_value = undef;
10 $reference = \"Reference of a String";
11```
12
13Perl has a few simple data types. Each is determined from the variable prefix symbol when declared, or when you want a non-scalar set of variables returned.
14
15* $variable - A scalar type
16* @variable - An array type
17* %variable - A hash type
18* & - A code type, though this is never a type of a variable
19
20Complex variables can hold multiple scalar variables. These are Arrays, Hashes, Globs, and Objects.
21
22When references or defining the whole structure, we use the type prefix as above, but when access a scalar value within one, we use the $ prefix to denote
23
24#### Scalar References
25
26A `reference` value does not hold one of these complex data types, but a "pointer" to one. A reference to a scalar can be used with the \\ referencing operator, the [ ] array reference construct, or a { } hash construct.
27
28The reference is dereferenced with the double-dollar ($$refname) variable.
29
30```perl
31 $i = 123; ## A scalar
32 $iref = \$i; #=> SCALAR(0x80108d678) ## Reference to scalar
33 $sref = \"Hello" ## A reference to a string or other literal
34 $$iref; #=> 123; ## Dereferencing the scalar reference
35```
36
37### Array
38
39The array holds a list of scalar values.
40
41```perl
42 @array = (1, 2, 'three', $file_handle, undef);
43 $array[1] #=> 2 ## Second element array (start counting at 0)
44 @array[1,2] #=> (2, 'three') ## A "slice" as list of elements selected from array
45
46 $#array #=> 4 ## Last element index of array. Avoid this odd syntax.
47 scalar(@array) #=> 5 ## Number of elements in the array
48
49 push @array, 123; ## Appends value(s) to the end of the array
50 pop @array; #=> 123 ## Removes and returns the last element of the array
51 unshift @array, 123; ## Prepends value(s) onto the head of the array
52 shift @array #=> 123 ## Removes and returns the first element from the array
53
54 foreach $element (@array) { # The foreach structure iterates over the loop
55 print $element
56 }
57
58 for ($i=0; $i<scalar(@array); $i++) { # The famous C-style for loop can be used
59 print $array[$i];
60 }
61
62 foreach my $i (0..$#array) { # Use the Range operator to iterate over the indexes of the array
63 print "Element $i is $array[$i]\n";
64 }
65
66 # Use map to iterate over the array, returning new array ($_ is the temp variable in block)
67 @array = map { $_ * 2 } @array; # This example doubles the values of each array element
68
69 # Use grep to generate list of elements matching your conditional expression ($_ is temp var)
70 @array = grep { $_ % 2 } @array; # Returns the odd numbers from an array of numbers
71
72```
73#### Array References
74
75To get an array reference, use the [1, 2, 3] syntax to create an array reference, or prefix your array variable with a backslash like \@array.
76
77Dereference an array with @$arrayref, with the $arrayref->[element] arrow for element references, or the @{array_ref_expression} syntax.
78
79```perl
80 $i = 123; ## A scalar
81 $iref = \$i; #=> SCALAR(0x80108d678) ## Reference to scalar
82 $$iref; #=> 123; ## Dereferencing the scalar reference
83
84 @arr = (1,2,3)
85 $aref = \@arr; #=> ARRAY(0x80108d678)
86 @$aref = (1,2,3); #=> ARRAY(0x80108d678) # Alternate syntax for dereferenced assignment
87 @$ref; #=> (1, 2, 3)
88 $aref = [1,2,3] #=> ARRAY(0x80108d678)
89 @$ref; #=> (1, 2, 3)
90 $ref->[1]; #=> 2 ## Second element of array
91 $$ref[1]; #=> 2 ## Alternate syntax
92 $aref = [split(/ /, $sentence)]; # wrap a function to return an array reference instead
93 $aref = [ map { $_ * 2 } @$aref ]; # Using map with an array reference
94
95 scalar(@$aref) #=> 3 ## Number of elements in the referenced array
96 $#{$a} #=> 2 ## Last element index in the references array (like @#arr)
97 $#{[]} #=> -1 ## ... Empty arrays return -1.
98
99 foreach (@{ arrayhref_function() }) { ... };
100
101 foreach my $i (0..$#{$aref}) { # Use the Range operator to iterate over the indexes of the array
102 print "Element $i is $array->[$i]\n";
103 }
104
105```
106
107### Hash
108
109A Hash is also known as a dictionary or associative array. It provides a key/value structure to set and retrieve values by a key value. It is a special case of a list, and decomposes back into a list when assigned or sent as a function parameter.
110
111```perl
112 %hash = (one=>1, two=>2, three=>3);
113
114 $hash{one}; #=> 1 ## The associated value for the key value of "one"
115 @hash{'one', 'two'}; #=> (1, 2) ## Returns a sliced list of values
116
117 %hash #=> ('one', 1, 'two', 2, 'three', 3) ## Decomposes into a list
118 keys %hash #=> ('one', 'two', 'three') ## List of keys
119 values %hash #=> (1, 2, 3) ## List of values
120 exists $hash{$key} #=> Boolean ## Hash operator returns true if key exists in the hash
121 delete $hash{three}; #=> 3 # Deletes key/value from hash, returns the value
122
123 %hash = %{ hashref_function() };
124
125 while ( ($key, $value) = each %hash) { # Iterates over a hash
126 print $key, $value;
127 }
128
129 foreach $key (keys %hash) { # Iterates over a hash by key value
130 print $key, $hash{$key};
131 }
132```
133
134Note: When iterating over a hash using `each`, it keeps a "cursor" in the hash of the current key/value pair. If you do not finish iterating, the next time you start iterating, it will continue where it left off instead of at the first key/value pair of the hash. To reset the cursor, call `keys %hash` before iteration.
135
136#### Hash References
137
138To get a hash reference, use the {key=>value} syntax instead, or prefix your variable name with a backslash like: \%hash.
139
140Dereference a hash with %$hashref, with the $arrayref->{key} arrow for value references, or the %{array_ref_expression} syntax.
141
142```perl
143 %hash = (one=>1, two=>2, three=>3);
144 $href = \%hash; #=> ARRAY(0x80108d6f0) ## Hashes are also arrays
145 %hash = %$hash; #=> ('one', 1, 'two', 2, 'three', 3)
146 $href = {one=>1, two=>2, three=>3};
147 #=> ARRAY(0x80108d6f0) ## Hashes are also arrays
148 $href->{one}; #=> 1 # Access a value by reference
149 $$href{one}; #=> 1 # Alternate syntax
150```
151
152## Usage: Passing data to functions
153
154When you call a Perl function, it generates an array of the arguments and invokes the function. The function uses the special default array variable, @_ and uses the positions of the arguments as the parameters.
155
156```perl
157 myfunction($i, $s); #=> sets @_ = (123, "String");
158```
159
160The called function parses the incoming argument list with standard Perl notation:
161
162```perl
163 ($first, $second, @rest) = @_;
164```
165
166That statement takes the incoming argument array, and puts the first element in $first, the second in $second, and the remaining arguments (if any) to into the @rest array.
167
168When you pass an array or hash (which is really just an array anyway) to a function, it "flattens" out the array and passes each value of the array as a positional parameter.
169
170```perl
171 myfunction($i, @arr, %hash); #=> sets @_ = (123, 1, 2, 3, 'name', 1, 1, "one", "etc.", $i);
172```
173
174Oops! Now myfunction() doesn't know where the array begin and ends, nor where the hash begins or ends. The only thing it knows for sure is the first argument since that in a simple scalar.
175
176This can be desired, as long as each parameter is a simple value, and the last parameter is an array or hash.
177
178```perl
179 myfunction($i, @arr); #=> Sets @_ to (123, 1, 2, 3);
180 #...
181 sub myfunction {
182 my ($i, @arr) = @_; #=> allows function to reconstruct the parameters
183 }
184```
185
186But what if you need to pass both an array AND a hash to a function? This is where references save the day. Since a reference to an array or hash is a single value, the reference to the whole array takes only one positional argument.
187
188
189```perl
190 myfunction($i, \@arr, \%hash);
191 #...
192 sub myfunction {
193 my ($i, $aref, $href) = @_; #=> $i is 123, $aref and $href are references.
194 @$aref; #=> (1, 2, 3)
195 %$hash; #=> (name=>1, 1=>"one", "etc."=>$i)
196 }
197```
198
199Function can also use this technique to return an array of values to a caller.
200
201```perl
202 return ($i, \@arr, \%hash);
203```
204
205There is also an added performance benefit of passing references instead of whole arrays and hashes. For large structures, it takes time copying each element from the array into the @_ variable. Instead, only a single reference variable is needed to be passed into the @_ argument list. In computer science, this is known as "passing by reference" instead of "passing by value".
206
207Lastly, when you pass a reference into a function, that function can change the value of the passed variable "in place" without getting returned explicitly. This technique is useful at time, but sometimes these "side effect" practices are discouraged, so use this only when it makes sense, okay?
208
209```perl
210 sub myfunction {
211 $iref = shift; # Shifts first value off of @_ array
212 ++$$iref; # Increment the value at the reference
213 }
214 #...
215 $j = 123; #=> 123
216 myfunction(\$j); # myfunction() will change the value of $j
217 $j; #=> 124
218```
219
220While this example demonstrated the concept, this is one of those cases where it is not okay to do this. I would instead not use the reference and have the code return the new value.
221
222### Simulating The Ruby Call
223
224NOTE: This is more advanced and references techniques from later in this document. If you are new to this topic, feel free to skip onto the next section.
225
226In the Ruby (1.9) language, which names Perl as a close ancestor, You can call a function like this:
227
228```ruby
229 my_func(data, hashkey:"value", hashkey2:123) { "This is a closure" }
230
231 def my_func(data, options={}, &block)
232 options #=> { hashkey: "value", hash_key2: 123 }
233 block.call #=> "This is a closure"
234 end
235
236 my_func2(1, 2, 3, 4, 5, 6, 7, 8, debug:true) { |x| x * 2 }
237
238 def my_func2(*args)
239 args #=> [1, 2, 3, 4, 5, 6, 7, 8, {debug: true}]
240 options = args.last.is_a?(Hash) ? args.pop : {} #=> {debug: true}
241 args #=> [1, 2, 3, 4, 5, 6, 7, 8]
242 args.map {|x| yield(x) } # The passed block is called with yield
243 end
244```
245
246Notice that the calls that look like named parameters ```hashkey:"value"``` are pooled into a hash and appended to the call arguments, that my_func captures in the variable ```options```. If a block is specified on the call, it will be assigned to a variable at the end starting with the ampersand like ```&block``` (though is still available using the yield command if not captured as such).
247
248In ```my_func2```, we expect any number of arguments, and the unspecified ones are assigned to the variable ```args``` using the "splat" (*) operator. This is how a perl function is invoked, where the parameters are assembled into an array, and the function must parse out the variables at the positions it expects.
249
250However, any name-value pairs specified at the end of the call are put into a hash, which is still passed as the last element of the args array. If we don't expect the args array to end with a hash, we can use this trick to pop off the hash as the last element of the args array, which we can use to control preferences for the function.
251
252We can use this trick as well with Perl when we also would not otherwise expect the last argument to be a hash reference or a closure (anonymous function reference).
253
254```perl
255 my_func2(1, 2, 3, 4, 5, 6, 7, 8, {debug=>1}, sub { 2 * shift });
256
257 sub my_func2 {
258 # Check if last argument is a CODE block...
259 my $block = scalar(@_) && ref($_[-1]) eq 'CODE' ? pop : sub {shift}; # Passed Closure?
260
261 # You can either do this to put the optional arguments into a hash reference...
262 my $options = scalar(@_) && ref($_[-1]) eq 'HASH' ? pop : {}; # as Hash Reference
263
264 # ... Or this to dereference it and store in a hash
265 my %options = scalar(@_) && ref($_[-1]) eq 'HASH' ? %{pop()} : (); # as Hash
266
267 my @args = @_; #=> (1, 2, 3, 4, 5, 6, 7, 8)
268 map { &$block($_) } @args;
269 }
270```
271
272Here, I inspected the special @_ argument array to see if the last element ($_[-1], we use $_ to access an element from @_, and the -1 index tells perl to wrap back around to the end of the array to point to the last element) is a code or hash reference. If it was, I use ```pop``` to take it off the end of the array, otherwise I set it to a default (empty) value.
273
274
275
276## Usage: Data Structures
277
278A `table` or 2-dimensional array is not a native perl datatype as it is in many languages. Instead, perl allows you to build your own as an array of arrays. Now since perl array elements can only be scalar variables, we need to use a reference instead. So a perl table is actually an array of references.
279
280```perl
281 @row1 = (1, 2, 3);
282 @row2 = (4, 5, 6);
283 @table = (\@row1, \@row2);
284
285 $table[0]->[1]; # => 2 ## Value of first row, second column
286 $table[0][1]; # => 2 ## Any second-level subscript/hash on array implies the ->
287```
288
289Often, it's best to bite the bullet and fully embrace a reference when you are using a data structure like this. It helps me to think of it as a starting point, and makes the syntax more friendly in the long run.
290
291```perl
292 $table = [ [1,2,3], [4,5,6] ]; # Table is a reference of arrays of arrays :-)
293 $table->[0][1]; #=> 2
294 $table[0][1]; # Wrong! # Error! Expecting $table[0]->[1] but $table is a reference, not array
295```
296
297See how I defined the table using the [ ] array reference syntax? It should make it more clear to write and read. Also, the table subscripts are now together, not separated by the -> dereferencing pointer.
298
299Also, see the difference of addressing table elements set up as starting with an array instead of a array reference? It can trip you up, and I suggest always use a reference to avoid the confusion, because mixing syntax styles in a program is painful. Using a consistent syntax within a large program and complex data structures reduces chances for errors.
300
301```perl
302 @table = ([1,2,3], [4,5,6]); # Avoid: array of references
303 $table[0][1]; #=> 2 ## While this works nicely...
304 $table[0]->[1]; #=> 2 ## ... this is what perl does
305
306 $table = [ [1,2,3], [4,5,6] ]; # Suggested: start off with a reference
307 $table->[0][1]; #=> 2 ## Only way to access the element
308
309 $reference->{key} # This makes a consistent usage for all data structures
310 $reference->{key}[0]; # ... Hash of arrays
311 $reference->[0]{key}; # ... Array of hashes
312```
313
314A result set of database rows are best represented as an array of hash references, where each row is a (colname=>value) hash. Again, let's start with a reference to the result set.
315
316```perl
317 $rows = []; # Initialize $rows as array reference
318 push @$rows, {id=>1, name=>"Allen"}; # Add first row, a hash reference.
319 push @$rows, {id=>2, name=>"Bob"}; # Second row
320
321 # Get at the data by $rows->[row_number]{column_name_as_hash_key}
322 $rows->[0]{name}; #=> Allen
323```
324
325Did you follow all that? You may want to parse through it a few times. Here are a few notes:
326
327* @$rows - Push expects an array, we use the @ to dereference the as an array so push can do its thing.
328* {column_name=>row_column_value} - We use the {} hash reference syntax to create the data row.
329* $rows - This returns an array reference for the result set
330* $rows->[0] - returns the first row on the rows array, which is a hash reference
331* $rows->[0]{name} - returns the corresponding value for the key "name" in the first row.
332
333## Dereferencing References of References
334
335Now for the fun part. We saw how to dereference a reference with the `<typeoperator>$referencevariable` syntax and -> operator to navigate through a series of nested references.
336
337```perl
338 @arr = @$array_reference;
339 %hash = %$hash_reference;
340 $i = $$scalar_reference;
341
342 $array_reference->[0];
343 $hash_reference->{key};
344 $array_of_hashes->[0]{key};
345 $array_of_arrays->[0][2]; ## a 2-Dimensional table
346 $three_dim_table->[0][1][2];
347 $arr_hash_array=>[1]{key}[2];
348```
349
350Now say we want to operate on a array reference returned from the -> operator. To dereferences an expression like this we use the `@{expression}` syntax for an array reference and the `%{expression}` syntax for a hash reference.
351
352Here is now this works with our 2-dimensional table structure
353```perl
354 $table = [ [1,2,3], [4,5,6] ];
355 $table->[0]; # Returns a reference to [1,2,3]
356 @row = @{$table->[0]}; # Returns the array of (1, 2, 3)
357 push @{$table->[0]}, 0; # $table is now [ [1,2,3,0], [4,5,6] ]
358
359 scalar(@{$table->[1]}) #=> 3 ## The number of items of the second row
360 $#{$table->[1]} #=> 2 ## Index of last element in the referenced array (-1 when empty)
361 @{$table->[1]}[1, 2] #=> (5, 6) ## Slice of array, returns table[1][1,2] as a list
362
363 foreach $row_ref (@$table) { # Iterate over each row
364 foreach $value (@$row_ref) { # Iterate over each column in that row
365 $value; # Do something with each value in the table
366 }
367 }
368
369 for ($i=$#{$table}; $i>=0; $i--) { # Reverse iteration by index
370 for ($j=$#{$table->[$i]}; $j>=0; $j--) { # ... reverse iteration for each row
371 $table->[$i][$j] += $prev; # Do something with that referenced location
372 $prev = $table->[$i][$j]; # ... Totally contrived example
373 }
374 }
375
376 foreach my $i (0..$#{$table}) { # Again, using the range operator
377 foreach my $j (0..$#{$table->[$i]}) {
378 print "table row $i column $j is: $table->[$i][$j]\n";
379 }
380 }
381```
382
383Now let's look at our result set "Array references of hash references"
384```perl
385 $rows = [ {id=>1, name=>"Allen"}, {id=>2, name=>"Bob"} ]; # Array Ref of Hashes
386 $rows->[0]; # Returns reference to the first row
387 %hash = %{$rows->[0]}; # Deferences the first row as a hash
388 @hash_keys = keys %{$rows->[0]}; # ... and now return its keys
389
390 foreach $hash_key (keys @{$rows->[0]}) { } # Iterate over the keys
391 while (($k,$v) = each %{$rows->[0]) { } # Iterate over the "row"
392
393 foreach $row_ref (@$rows) { # Iterate over each row
394 while (($k,$v) = each %{$rows->[0]) { # Iterate over each key-value pair
395 ($k, $v); # Do something with each pair
396 }
397 }
398```
399
400## Inspecting the reference for type
401
402Okay, now imagine you need to write a subroutine that takes a reference, and need to determine what the datatype is for the reference?
403
404The `ref` unary operator takes a variable and returns the datatype. It is the "type of" operator, but does not distinguish between scalar types (string, number, undef, file handles).
405
406```perl
407 ref 'asdf' #=> '' ## Non-reference values return the empty string
408 ref [1,2,3] #=> 'ARRAY'
409 ref {a=>12} #=> 'HASH'
410 ref sub {} #=> 'CODE' ## Code object (see below)
411 ref \123 #=> 'SCALAR' ## Reference to a scalar
412 ref new MyClass #=> 'MyClass' ## Objects return their package/class name
413
414 ref undef #=> '' ## Even undefined values (null/nil) are scalar
415 defined(undef); #=> False ## A False condition, but no value returned
416
417 $r = [{a=>1}];
418 ref $r #=> 'ARRAY' ## Array of Hashes
419 ref $r->[0] #=> 'HASH' ## Deference to the Hash
420```
421
422Congratulations, you are now a master of basic perl references!
423
424## References to Code
425
426But wait! There's more! You can also have references to "code" functions and closures. Older versions of perl used the `&myfunction()` syntax to call a function, but the & operator has been dropped as it was not necessary. However, it is still needed to deferences a code reference.
427
428```perl
429 sub myfunc { 123; } # A simple function
430
431 $code_ref = \&myfunc; # Take a reference to your subroutine
432
433 # These do not work! &myfunc() will alway run the function, not reference it
434 &myfunc(); #=> 123 ## The parens executes the code
435 \&myfunc(); #=> SCALAR(0x100804ed0) ## Executes Returns ref to 123
436
437 @array = my_map(\@array, \&myfunc); # Pass code reference to another function.
438
439 # Execute the code reference. We can also pass in any arguments it needs.
440 &$code_ref(); #=> 123
441```
442
443### Closures
444
445Closures are a cool trick, stolen outright from the Lisp universe. It is a block of code that is passed to another function or stored for later execution, much like we saw before.
446
447The really cool part is this code block executes in the *context* of when it was defined. It has access to all the variables in the scope when it was created, and can alter them, even when invoked from within another function.
448
449One of the useful things we can do with closures is to create a callback code block that injects our specific logic into a general purpose routine.
450
451Closures are "anonymous code blocks" using the `sub { }` syntax (like a subroutine definition without a name).
452
453```perl
454 $i = 1;
455 $closure = sub { ++$i; } # Reference to a closure
456 &$closure(); # Run the reference
457 $i; #=> 2
458```
459
460Let's build a useful function to tie this all together. Perl has a `map` construct that iterates over an array, injects a value into a block, and returns an array of values returned from the block. It does *not* use a closure, but it a language syntax construct. For instance:
461
462```perl
463 @array = ( 1, 2, 3);
464 @array = map { $_ + 1 } @array; # Adds 1 to each element in the array
465 @array #=> (2, 3, 4)
466
467 # Alternate (non-map) way to do this:
468 @result = ();
469 foreach (@array) { push @result, $_ + 1; }
470 @array = @result;
471```
472
473It's a simple, but rather ugly syntax. It sets the $_ variable inside the block for each value of the array.
474
475Suppose we want to create an map-like iterator for a hash. We can write a general routine, map_hash(), that iterates over a hash, and executes a passed closure (or code block) for each key-value pair. The routine passed back a key-value pair, either the same or changed. map_hash() returns a new hash of the result pairs.
476
477```perl
478 sub map_hash {
479 ($hash_ref, $block_ref) = @_; # Args: map_hash(\%hash, sub {} );
480 keys %$hash_ref; # Resets hash iterator in case it was not finished
481 %result = ();
482 while ( ($k,$v) = each %$hash_ref) {
483 ($k, $v) = &$block_ref($k, $v); # Calls the closure or code block
484 %result{$k} = $v; # Place new key-value in result hash
485 }
486 %result; # Returns the new hash
487 }
488
489 # Call map_hash to upper-case the keys of a hash.
490 %hash = (a=>1, b=>2);
491 %hash = map_hash(\%hash, \&uc_hash_keys);
492 %hash; #=> (A=>1, B=>2)
493
494 sub uc_hash_keys {
495 ($k, $v) = @_; # Input arguments: key, value pair
496 (uc $k, $v); # Return upper-cased key, value pair
497 }
498
499 # Call map_hash to sum the values of all keys in the hash
500 $total = 0; # The closure has access to all local vars!
501 %hash = map_hash(\%hash,
502 sub { # Create a closure to
503 ($k, $v) = @_; # Input arguments: key, value pair
504 $total += $v; # Adds value to total defined above
505 ($k, $v); # Return unchanged key, value pair
506 }
507 );
508 $total; #=> 3
509```
510
511# Classes and Object Oriented Perl
512
513Wait! What is this doing here? We are talking about Perl References, right? Well, the perl object model really is just a reference "blessed" with a package name. You can execute any method (a function in OOP is now called a method) in that package using the -> operator.
514
515```perl
516package Person; # Define our Person class
517
518sub new { # Constructor method
519 ($class, %attributes) = @_; # * Receives the package and any arguments
520 my $self = \%attributes; # * Create a hash reference as instance
521 bless $self, $class; # * Tells perl $self is an instance of Person
522} # * bless returns $self, which is returned to caller
523
524sub talk {
525 ($self, $message) = @_; # Self is the object reference always passed in
526 print "$self->{name} says $message \n";
527}
528
529package main; # Change back to our "main" namespace
530
531$person = {id=>1, name=>"Allen"}; # $person is a hash reference
532bless $person, Person; #=> Person=HASH(0x100804ed0), instance created without "new"
533
534# Or we can use the "new" syntax we see in other languages
535$person = new Person(id=>1, name=>"Allen")
536
537# Now $person is a instance of class Person (implemented with a hash).
538
539# Call a method on the person object reference
540$person->talk("hi"); #=> Allen says hi
541
542# This is syntax-sugar for the true calling notation (which explains the $self arg)
543$person = Person::new(Person, id=>1, name=>"Allen");
544Person::talk($person, "hi");
545```
546
547Of course, there is more to understand about object-oriented perl than this basic example. I wanted to demonstrate that perl objects are also references, and require the same syntax.
548
549Also, you see that all perl objects are specially "blessed" references of perl hashes, arrays, or other things you can reference. Though, you will find that 99.99% of the time, it will be a hash, because the hash keys become the instance variables of the object.