I'll concentrate on the mistakes. If I were to criticise all the other many weird formulations and expressions in this guide which make it hard to unambiguously understand what the author meant, I would still sit and be typing here tomorrow.
----
> A code comment in Perl begins with a hash #
Hashes are already something different in Perl. Avoid ambiguity, use the common name of that character: number sign.
> procedure
This word is used through-out, but the official Perl documentation does not mention it. Use the word subroutine (or just sub for short) instead.
> The $ prefix references a variable as a scalar
> Array variables use the prefix @
This is the wrong explanation. The sigil denotes the mode of access, @ indicating the expression evaluating to a list value, $ indicating a single value. This becomes clear when one examines slices of a compound data structure.
@arr = ("foo","bar","baz");
$arr[1]; # "bar"
@arr[2,3]; # ("bar", "baz")
%hash = ("foo", 1, "bar", 2);
$hash{"foo"}; # 1
@hash{"foo", "bar"}; # (1, 2)
The guide mentions the change from @ to $ or from % to $ only in passing without explanation, and does not mention slices at all.
> Hash variables expect an array for initialization.
No, a list.
> three contexts in which an expression may be evaluated:
> 1. scalar
> 2. array
> 3. void
No, the second is list context.
> Is localtime() returning a scalar, or an array?
No, a scalar or a list.
> By default, the arguments to a procedure are in the array context, which means that the comma operator expects both of its operands to be arrays. It promotes them to single-element arrays if they are scalars.
> It seems that the function call still flattened out the arrays (and hashes) when making the call.
This is completely misleading. A sub takes always a list. What is described here has nothing to do with arguments, but is the consequence of the specifics of how values are evaluated into a list. This also happens, for example, on list assignment.
> all of the following are equivalent procedure calls:
> print3 (1,2,3) ;
> &print3 (1,2,3) ;
This is wrong, there is a difference, it just did not show up in the example.
> In fact, the argument isn’t even hash, despite what the specifier says
Refer to the documentation: when not backslashed, % is defined to behave like @.
> sub use_hash (%) {
> print $_[0]{"foo"} ;
> print $_{"foo"} ;
> print @_{"foo"} ;
> }
> use_hash ("foo" => 1701) ; # prints nothing
No wonder. The code is broken.
@_ contains a plain list value. To access it with a hash subscript, turn it into a hashref first.
print +{ @_ }->{"foo"};
print ${ {@_} }{"foo"};
> The specifier & expects to receive a function
Not function, coderef is the appropriate word.
> To accept a bareword filehandle as an argument, it becomes necessary to use the rarely used * prototype specifier
Simply passing *F is also possible, no prototype involved.
> The repetition operator x repeats a string or an array,
No, it repeats single or list values. Scalars are coerced into their string representation, and lists are simply repeated unchanged.
----
Closing words: This is amateur hour, not worthy of a professor. Advice for next time: consult domain experts and have them proof-read before publishing, and also always give your documents a last-modification date and version history, or at least a version identifier.