I once wrote one of these before for @NegativeMjark but I think I lost it. So here's another.
All you need to know is:
- 
$foois a scalar (i.e. a single dimensional variable)
- 
@foois an array.$foo[n]is the element of an array.
- 
%foois a hash.$foo{'moo'}aka$foo{moo}is the value in the hash for key'foo'.
- 
\is the reference operator. it returns a scalar which points to the address of the variable (like&in C).
- 
(1, 2, 3)is a list. (an array is a variable which contains a list).
- 
[1, 2, 3](rarely:\(1,2,3)) is a reference to a list - aka arrayref
- 
$foo->[n]gives an element of an arrayref
- 
@$fooaka@{$foo}dereferences an arrayref back into an array
- 
(a=>1, b=>2) or ('a'=>1, 'b'=>2)is a hash.
 (technically, it's a list which you can assign to a hash to initialise it -=>is a synonym for,.%foo = ('a', 1, 'b', 2)would do the same thing).
- 
{a=>1, b=>2} or {'a'=>1, 'b'=>2}(rarely:\(a=>1, b=>2)) is a reference to a hash - aka hashref.
- 
$foo->{'moo'}aka$foo->{moo}is an element of a hashref
- 
%$fooaka%{$foo}dereferences a hashref back into an hash
- 
$foo->{bar}->{quux}or$foo->{bar}{quux}lets you drill into a nested datastructure - likefoo.bar.quuxelsewhere.
- 
$foo->{bar}->[0]or$foo->{$bar}[0]also works.
- 
$foo->bar()calls method bar on object$foo.
- 
compare numbers with <,==,>,<=.>=,!=,<=>(lattermost is -1 if a<b, +1 if a>b, 0 if a==b)
- 
compare strings with lt,eq,gt,le,ge,ne,cmp
- 
you must always run with use strict; use warnings;.
- 
subdeclares a function. you typically don't declare a prototype of the arguments it takes, although you could specify a cryptic message signature made out of sigils, but nobody does.
- 
the arguments to the function are available in the @_array variable.
- 
so: sub moo { my $bar = shift; }is the equivalent tofunction moo(bar) {}in JS.
- 
if you skip the argument for a given function, it typically operates on the 'topic' variable, which is $_or@_. So in the example above,shiftis short forshift @_. This is typically the default iterator variable if you don't specify one, e.g.foreach (@foo) { do something with $_ }
- 
mydeclares a local scope similar toletin JS.
- 
ourdeclares a global scope.
- 
every operand is evaluated in a context - typically either scalar or list. This lets functions behave differently when you assign to a list rather than a scalar; e.g. my (@foo) = localtimereturns an array of the day, month, etc, whereasmy ($foo) = localtimereturns a unix epoch timestamp.- If it's ambiguous whether you wanted a list or a scalar, you use the scalarkeyword to force it to be scalar, or, more rarely, assign through an empty list to force it to be a list (e.g.= () =).
- Usefully, the value of an array in a scalar context is its length. so: @a = (1, 1, 1); $b = @a;,$bis 3 (as isscalar @a).
 
- If it's ambiguous whether you wanted a list or a scalar, you use the 
- 
you can put conditionals after expressions as well as before them, in order to make the code read more like English: - if ($moo) { bar(); }is often written as- bar() if $moo;.
 
- 
unlessis a synonym forif not, in order to make the code read more like English:foo() unless bar;.
- 
hashes 'autovivify'. which means that my $foo; $foo->{bar}{quux}{baz} = 1;will do the right thing, rather than needing you to initialise each layer of the datastructure as an empty hash. It's great when it's what you wanted, but can blow your leg off.
- 
There are lots of archaic magic variables provided by the runtime, for getting at things like line separators, line buffering behaviour, unix user ID. Just use perldoc perlvarif you see something like$/or$|and have no idea what's going on. They all have sensible names too (like$INPUT_RECORD_SEPARATORand$OUTPUT_AUTOFLUSH) if only people would ever use them.
- 
pretty much everything else you can find out via perldoc -f whatever.