<?xml version="1.0"?>
<?xml-stylesheet type="text/xml" href="presenter.xsl"?>
<slideshow>
	<title>Introduction to Perl</title>
	<slide>
		<title>Introduction to Perl</title>
		<body>
			<p>By Karl Voelker</p>
		</body>
	</slide>
	<slide>
		<title>What is Perl?</title>
		<body>
			<ul>
				<li>Dynamically-typed</li>
				<li>Multi-paradigm</li>
				<li>Multi-platform</li>
				<li>Flexible</li>
				<li>Fun!</li>
			</ul>
		</body>
	</slide>
	<slide>
		<title>Dynamic Typing</title>
		<body>
			<p>In Perl:</p>
			<ul>
				<li>Values have types</li>
				<li>Variables do not</li>
			</ul>
		</body>
	</slide>
	<slide>
		<title>Multiple Paradigms</title>
		<body>
			<dl>
				<dt>Imperative</dt>
				<dd>Subroutines, control structures, 
					mutable variables</dd>
				<dt>Object-Oriented</dt>
				<dd>Polymorphism, modules, 
					multiple inheritance</dd>
				<dt>List-Oriented</dt>
				<dd>List assignment, list operators</dd>
				<dt>Generic</dt>
				<dd>Via dynamic typing</dd>
				<dt>Functional</dt>
				<dd>First-class functions, closures</dd>
			</dl>
		</body>
	</slide>
	<slide><title>Variables</title><body>
		<p>Three kinds of variables:</p>
		<dl>
			<dt>Scalar</dt>
			<dd>Numbers, strings, references</dd>
			<dt>Array</dt>
			<dd>Ordered list of scalars</dd>
			<dt>Associative Array (Map, Hash)</dt>
			<dd>Key/value pairs of scalars</dd>
		</dl>
	</body></slide>
	<slide><title>Sigils</title><body>
		<p>A variable name is always prefixed by a sigil.</p>
		<p>The sigil denotes the type of the value, 
			not the type of the variable!</p>
		<!-- this div erases some blank space that is pushing 
			the lists down below the red line -->
		<div style='margin-top: -1em'>
		<div class='col'>
		<dl>
			<dt><tt>$foo</tt></dt>
			<dd>Scalar</dd>
			<dt><tt>@foo</tt></dt>
			<dd>Array</dd>
			<dt><tt>$foo[0]</tt></dt>
			<dd>Scalar from an array</dd>
			<dt><tt>@foo[0,3,4]</tt></dt>
			<dd>Slice from an array</dd>
		</dl>
		</div>
		<div class='col'>
		<dl>
			<dt><tt>%foo</tt></dt>
			<dd>Hash</dd>
			<dt><tt>$foo{'bar'}</tt></dt>
			<dd>Scalar from a hash</dd>
			<dt><tt>@foo{'bar', 'baz'}</tt></dt>
			<dd>Slice from a hash</dd>
		</dl>
		</div>
		</div>
	</body></slide>
	<slide><title>Assignment</title><body>
		<ol>
		<li><tt>$foo = 1;</tt></li>
		<li><tt>($foo, $bar) = (1, 2);</tt></li>
		<li><tt>($foo, $bar, $baz) = @quux;</tt></li>
		<li><tt>($foo, undef, $baz) = @quux;</tt></li>
		<li><tt>@foo = (1, "two", 3);</tt></li>
		<li><tt>$foo[0] = 'one';</tt></li>
		<li><tt>@foo[1,2,3] = (2, 3, 4);</tt></li>
		<li><tt>%foo = ('foo' => 1, 'bar' => 'baz');</tt></li>
		<li><tt>$foo{'bar'} = 342;</tt></li>
		<li><tt>@foo{'bar', 'baz'} = (7, 8);</tt></li>
		</ol>
	</body></slide>
	<slide><title>Numbers</title><body>
		<ul>
		<li><tt>1</tt></li>
		<li><tt>2.0</tt></li>
		<li><tt>3.0e4</tt></li>
		</ul>
	</body></slide>
	<slide><title>Numeric Operators</title><body>
		<p>Integer operations are performed if all operands are 
			integers.</p>
		<div class='col'>
		<dl>
		<dt><tt>+ - * /</tt> (binary)</dt>
		<dd>Obvious</dd>
		<dt><tt>% (binary)</tt></dt>
		<dd>Modulo</dd>
		<dt><tt>** (binary)</tt></dt>
		<dd>Exponentiation</dd>
		<dt><tt>-</tt> (unary, prefix)</dt>
		<dd>Negation</dd>
		</dl>
		</div>
		<div class='col'>
		<dl>
		<dt><tt>++ --</tt> (unary, prefix or postfix)</dt>
		<dd>Increment/decrement, as in C</dd>
		<dt><tt>+= -= *= /= %= **=</tt></dt>
		<dd>Like C</dd>
		</dl>
		</div>
	</body></slide>
	<slide><title>Strings</title><body>
		<ul>
		<li>Double-quoted (escapes and interpolation):
			<ul>
			<li><tt>"foo"</tt></li>
			<li><tt>"bar\n"</tt></li>
			<li><tt>"$foo[2]bar$baz@quux"</tt></li>
			</ul>
		</li>
		<li>Single-quoted (literal only):
			<ul>
			<li><tt>'foo'</tt></li>
			<li><tt>'bar'</tt></li>
			</ul>
		</li>
		</ul>
	</body></slide>
	<slide><title>String Operators</title><body>
		<dl>
		<dt><tt>.</tt> (period)</dt>
		<dd>Concatenation</dd>
		<dt><tt>length</tt></dt>
		<dd>Length</dd>
		<dt><tt>substr</tt></dt>
		<dd>Substring</dd>
		<dt><tt>chomp</tt></dt>
		<dd>Remove trailing newlines</dd>
		<dt><tt>sprintf</tt></dt>
		<dd>Like C</dd>
		<dt><tt>uc, lc</tt></dt>
		<dd>Uppercase, lowercase</dd>
		</dl>
	</body></slide>
	<slide><title>Regular Expressions</title><body>
		<p>Regular expressions are another language altogether. 
			Here is how Perl uses them:</p>
		<dl>
		<dt><tt>($username, $domain) = <br/>
			$email =~ /^(.*)\@(.*)$/;</tt>
			</dt>
		<dd>Extract parenthesized parts of a match</dd>
		<dt><tt>$real =~ /^(\d+)\.(\d+)$/;<br/>
			($int, $frac) = ($1, $2);</tt></dt>
		<dd>Extract parenthesized parts another way</dd>
		<dt><tt>$tainted =~ s/\W//g;</tt></dt>
		<dd>Global substitution</dd>
		</dl>
	</body></slide>
	<slide><title>Subroutines</title><body>
		<dl>
		<dt>Definition:</dt>
		<dd>
			<ul>
			<li><tt>sub foo { ... }</tt></li>
			<li><tt>sub { ... }</tt> (anonymous)</li>
			</ul>
		</dd>
		<dt>Parameters come in <tt>@_</tt>:</dt>
		<dd><pre>sub foo {
	my ($a, $b) = @_;
	return $a + $b;
}</pre></dd>
		<dt>Call:</dt>
		<dd>
			<ul>
			<li><tt>foo(1, 2);</tt></li>
			<li><tt>foo 1, 2;</tt> (<tt>foo</tt> must already 
				be declared)</li>
			<li><tt>goto &amp;foo;</tt> (replaces current call 
				on the stack)</li>
			</ul>
		</dd>
		</dl>
	</body></slide>
	<slide><title>Lists</title><body>
		<p>Lists <em>flatten</em>:</p>
		<ul>
		<li><tt>(1, (2, 3), 4)</tt> becomes 
			<tt>(1, 2, 3, 4)</tt></li>
		<li>With <tt>@a = ('a', 'b', 'c')</tt>, <br/>
			<tt>(@a, 'd')</tt> becomes 
			<tt>('a', 'b', 'c', 'd')</tt>.</li>
		</ul>
	</body></slide>
	<slide><title>List Creation</title><body>
		<p>Some other ways:</p>
		<ul>
		<li><tt>1..5</tt> becomes <tt>(1, 2, 3, 4, 5)</tt>.</li>
		<li><tt>qw/some words/</tt> becomes <br/>
			<tt>('some', 'words')</tt>.</li>
		</ul>
	</body></slide>
	<slide><title>Lists and Arrays</title><body>
		<p>Lists and arrays are similar and related, but not 
			identical:</p>
		<ul>
		<li>An array is a variable.</li>
		<li>You can always use an array as a list.</li>
		<li>Some operators act in-place on array variables, 
			so they can't work with other lists.</li>
		</ul>
	</body></slide>
	<slide><title>Array Operators</title><body>
		<dl>
		<dt><tt>push</tt></dt>
		<dd>Add items to end of array</dd>
		<dt><tt>pop</tt></dt>
		<dd>Remove item from end of array</dd>
		<dt><tt>unshift</tt></dt>
		<dd>Add items to front of array</dd>
		<dt><tt>shift</tt></dt>
		<dd>Remove item from front of array</dd>
		</dl>
	</body></slide>
	<slide><title>List Operators</title><body>
		<dl>
		<dt><tt>reverse</tt></dt>
		<dd>Return list in opposite order</dd>
		<dt><tt>sort</tt></dt>
		<dd>Return sorted list</dd>
		<dt><tt>grep</tt></dt>
		<dd>Return list of items meeting some criteria</dd>
		<dt><tt>map</tt></dt>
		<dd>Return list of results of subroutine call on each 
			list item</dd>
		</dl>
	</body></slide>
	<slide><title><tt>sort</tt></title><body>
		<pre>my @a = qw/some words in 
	no particular order/;

my @sorted = sort @a;

my @sorted_by_length = sort {
	length $a &lt;=&gt; length $b
} @a;

my @sorted_by_last_four = sort {
	substr($a, -4) cmp substr($b, -4);
} @a;</pre>
	</body></slide>
	<slide><title><tt>grep</tt></title><body>
		<pre>my @s = (1..20);

my @one_digit = grep /^.$/, @s;

my @even = grep {
	$_ % 2 == 0
} @s;

my @random_75_percent = grep {
	int(rand * 100) &lt; 75
} @s;</pre>
	</body></slide>
	<slide><title><tt>map</tt></title><body>
		<pre>my @s = (1..20);

my @squares = map {
	$_ * $_
} @s;

my @products = map {
	my $first = $_;
	map {
		my $product = $first * $_;
		"$first * $_ = $product\n"
	} @s
} @s;</pre>
	</body></slide>
	<slide><title><tt>Hash Operators</tt></title><body>
		<dl>
		<dt><tt>keys</tt></dt>
		<dd>Returns a list of the keys of a hash</dd>
		<dt><tt>values</tt></dt>
		<dd>Returns a list of the values of a hash</dd>
		<dt><tt>exists</tt></dt>
		<dd>Returns whether or not a key exists in a hash</dd>
		</dl>
		<p>Hashes aren't ordered, so don't count on the order of 
			<tt>keys %h</tt> to match the order of 
			<tt>values %h</tt>!</p>
	</body></slide>
	<slide><title><tt>Booleans?</tt></title><body>
		<p>Perl doesn't have a boolean type. Some values are 
			considered false, and the rest are considered 
			true:</p>
		<h2>False values:</h2>
		<ul>
		<li><tt>undef</tt></li>
		<li>Zero (integer or real)</li>
		<li>Empty string</li>
		<li>The string <tt>"0"</tt>, but not <tt>"00"</tt> 
			or <tt>"0.0"</tt></li>
		<li>Empty list (or array)</li>
		<li>Empty hash</li>
		</ul>
	</body></slide>
	<slide><title><tt>Logical Operators</tt></title><body>
		<p>Perl has low- and high-precedence logical operators:</p>
		<table>
		<thead>
		<tr><th>High</th><th>Low</th><th>Notes</th></tr>
		</thead>
		<tbody>
		<tr><td><tt>&amp;&amp;</tt></td><td><tt>and</tt></td>
			<td></td></tr>
		<tr><td><tt>||</tt></td><td><tt>or</tt></td>
			<td></td></tr>
		<tr><td></td><td><tt>xor</tt></td>
			<td></td></tr>
		<tr><td><tt>!</tt></td><td><tt>not</tt></td>
			<td>Prefix</td></tr>
		</tbody>
		</table>
	</body></slide>
	<slide><title><tt>undef</tt></title><body>
		<p><tt>undef</tt> is an operator that:</p>
		<ul>
		<li>Undefines a variable, if given an argument</li>
		<li>Returns the undefined value</li>
		</ul>
		<p>We usually call the undefined value <tt>undef</tt>.</p>
		<p>Check if a value equals <tt>undef</tt> with 
			<tt>defined</tt>.</p>
	</body></slide>
	<slide><title><tt>undef</tt> and <tt>exists</tt></title><body>
		<p>A key can exist in a hash but have the value 
			<tt>undef</tt>:</p>
		<ul>
		<li>Given <tt>$h{'key'} = undef</tt>,</li>
		<li><tt>exists $h{'key'}</tt> is true, but</li>
		<li><tt>defined $h{'key'}</tt> is false.</li>
		</ul>
		<p>When you access a non-existent hash index, you get 
			<tt>undef</tt>. This sometimes causes bugs.</p>
	</body></slide>
	<slide><title>Conditionals</title><body>
		<dl>
		<dt>Block conditionals</dt>
		<dd><tt>if (condition) { statement; statement; }</tt><br/>
		<tt>unless (condition) { statement; statement; }</tt></dd>
		<dt>One-line conditionals</dt>
		<dd><tt>statement if condition;</tt><br/>
		<tt>statement unless condition;</tt></dd>
		<dt>Expression conditionals</dt>
		<dd><tt>condition ? if-true : if-false</tt></dd>
		</dl>
	</body></slide>
	<slide><title>Loops</title><body>
		<dl>
		<dt>Block loops</dt>
		<dd><tt>for var (list) { statement; statement; }</tt><br/>
		<tt>for (init, condition, increment) { ... }</tt><br/>
		<tt>while (condition) { ... }</tt><br/>
		<tt>until (condition) { ... }</tt><br/>
		<tt>do { ... } while (condition);</tt><br/>
		<tt>do { ... } until (condition);</tt></dd>
		</dl>
		<p>You may write <tt>for</tt> as <tt>foreach</tt>.</p>
	</body></slide>
	<slide><title>Loop Control</title><body>
		<p>Loops may be labelled, with <tt>LABEL:</tt>.</p>
		<p>With nested loops, outer loops must be labelled to 
			use loop control on them.</p>
		<dl>
		<dt><tt>redo LABEL;</tt></dt>
		<dd>Jump to the beginning of the current iteration
			of this loop.</dd>
		<dt><tt>next LABEL;</tt></dt>
		<dd>Jump to the next iteration of this loop.</dd>
		<dt><tt>last LABEL;</tt></dt>
		<dd>Leave this loop immediately.</dd>
		</dl>
	</body></slide>
	<slide><title><tt>continue</tt></title><body>
		<p>A <tt>continue</tt> block is executed between the loop 
			body and loop test.</p>
		<p>If you use <tt>next</tt> to skip part of the loop body, 
			the <tt>continue</tt> block is still executed.</p>
	</body></slide>
	<slide><title>More on <tt>continue</tt></title><body>
		<pre>while (condition) {

	# redo jumps here
	do_stuff;

} continue {

	# next jumps here
	do_other_stuff;
	# jump to loop test

}

# last jumps here</pre>
	</body></slide>
	<slide><title>Variable Scope</title><body>
		<p>If you don't specify otherwise, any variable you use 
			is global.</p>
		<p>You should <tt>use strict</tt> to prevent 
			accidental globals.</p>
		<h2>Lexical Scope</h2>
		<p>Most of your variables should be lexically scoped:</p>
		<ul>
		<li>my $foo;</li>
		<li>my $foo = 3;</li>
		<li>my ($foo, $bar) = (3, 4);</li>
		<li>my ($foo, $bar);</li>
		</ul>
		<p>A lexically-scoped variable can only be used from within 
			its enclosing block. This is like C.</p>
	</body></slide>
	<slide><title><tt>local</tt></title><body>
		<ul>
		<li><tt>local</tt> is not <tt>my</tt>.</li>
		<li>You shouldn't use <tt>local</tt>, usually.</li>
		<li>A <tt>local</tt> variable isn't a new variable: 
			it's a global.</li>
		<li>The <em>changes</em> to the variable are local to the 
			block: they are reverted at the block's end.</li>
		</ul>
	</body></slide>
	<slide><title><tt>my</tt> and <tt>local</tt></title><body>
		<pre>($a, $b) = (1, 2);
sub print_ab {
	print "$a $b\n";
}
sub foo {
	local ($a) = 3;
	my ($b) = 4;
	print_ab;
}
foo;
print_ab;
</pre>
		<h2>Output:</h2>
		<pre>3 2
1 2</pre>
	</body></slide>
	<slide><title>References</title><body>
		<p>A reference:</p>
		<ul>
		<li>Is a scalar</li>
		<li>Knows the location of some other variable</li>
		</ul>
		<p>A referent (the thing to which a reference refers):</p>
		<ul>
		<li>Might not have a "real" variable name</li>
		<li>Will exist as long as there are any references to it</li>
		</ul>
	</body></slide>
	<slide><title>References to Existing Variables</title><body>
		<p>Use <tt>\</tt> to get a reference to an existing 
			variable (or value):</p>
		<pre>$a = "foo";
$a_ref = \$a;
@b = ('foo', 'bar');
$b_ref = \@b;</pre>
	</body></slide>
	<slide><title>Reference Semantics</title><body>
		<p>Assignment makes a <em>copy</em>...</p>
		<p>...but reference assignment only copies the reference, 
			not the referent.</p>
	</body></slide>
	<slide><title>Dereferencing</title><body>
		<p>Dereferencing a reference gives you the referent 
			variable:</p>
		<table style="font-size:0.8em">
		<tr><th>Variable</th><th>Reference</th>
			<th>Variable by dereference</th></tr>
		<tr><td><tt>$a = 1;</tt></td>
			<td><tt>$b = \$a;</tt></td>
			<td><tt>$$b</tt></td></tr>
		<tr><td><tt>@c = (1, 2);</tt></td>
			<td><tt>$d = \@c;</tt></td>
			<td><tt>@$d</tt></td></tr>
		<tr><td><tt>%e = (1 => 2);</tt></td>
			<td><tt>$f = \%e;</tt></td>
			<td><tt>%$f</tt></td></tr>
		</table>
	</body></slide>
	<slide><title>Dereference Combos</title><body>
		<p>When you want to immediately do something with the 
			referent, you will probably use one of these:</p>
		<dl>
		<dt>Index an array</dt>
		<dd><tt>$array_ref->[2]</tt></dd>
		<dt>Index a hash</dt>
		<dd><tt>$hash_ref->{'foo'}</tt></dd>
		<dt>Call a subroutine</dt>
		<dd><tt>$sub_ref->(1, 2, 3)</tt></dd>
		</dl>
	</body></slide>
	<slide><title>Subroutine References</title><body>
		<p>The familiar <tt>\</tt> will allow us to reference 
			a subroutine.</p>
		<p>The subroutine can then be an argument or return value!</p>
		<pre>sub foo {
	do_something;
}
$sub_ref = \&amp;foo;</pre>
	</body></slide>
	<slide><title>Closures</title><body>
		<p>A subroutine may access lexically-scoped variables 
			that were valid when it was created:</p>
		<pre>sub make_adder {
	my ($a) = @_;
	return sub {
		my ($b) = @_;
		return $a + $b;
	};
}</pre>
	</body></slide>
	<slide><title>Literal References</title><body>
		<p>You will often want to create an array or hash 
			reference directly:</p>
		<div class="col">
		<h2>Bad</h2>
		<pre>@a = (1, 2);
$a = \@a;

%h = (1 => 2);
$h = \%h;</pre>
		</div>
		<div class="col">
		<h2>Good</h2>
		<pre>$a = [1, 2];


$h = {1 => 2};</pre>
		</div>
	</body></slide>
	<slide><title>Input and Output</title><body>
		<p>You may use a real file handle, or a reference to one, 
			when performing input and output.</p>
		<p>Real file handles cannot be lexically scoped, whereas 
			references can.</p>
	</body></slide>
	<slide><title>Opening Files</title><body>
		<h2>For reading:</h2>
		<pre>my ($fh);
open $fh, 'filename';

open my ($fh), 'filename';</pre>
		<h2>For writing:</h2>
		<pre>open my ($fh), '>', 'filename';
open my ($fh), '>filename';</pre>
	</body></slide>
	<slide><title>Input</title><body>
		<p>Use the <tt>&lt;&gt;</tt> operator to read: 
			<tt>&lt;$fh&gt;</tt>.</p>
		<p><tt>&lt;&gt;</tt> is aware of its <em>context</em>:</p>
		<dl>
		<dt>In <em>scalar context</em> it reads one line:</dt>
		<dd><tt>$line = &lt;$fh&gt;;</tt></dd>
		<dt>In <em>list context</em> it reads all remaining 
			lines as a list:</dt>
		<dd><tt>@lines = &lt;$fh&gt;;</tt></dd>
		</dl>
	</body></slide>
	<slide><title>What ends a line?</title><body>
		<p>You can change what characters are considered 
			end-of-line delimeters by <tt>readline</tt>:</p>
		<pre>$/ = " \t\n";
@tokens = &lt;$fh&gt;;

$/ = '';
$whole = &lt;$fh2&gt;;</pre>
	</body></slide>
	<slide><title>Standard Input</title><body>
		<p>Standard input's file handle is <tt>STDIN</tt>.</p>
		<p>The <tt>&lt;&gt;</tt> operator defaults to reading from 
			STDIN.</p>
		<p>Shortcut: <tt>while (&lt;&gt;)</tt> means 
			<tt>while ($_ = &lt;&gt;)</tt>.</p>
	</body></slide>
	<slide><title>Output</title><body>
		<p>Use <tt>print</tt> to print:</p>
		<dl>
		<dt><tt>print 'foo', 'bar', 'baz';</tt></dt>
		<dd>Print to standard output.</dd>
		<dt><tt>print $fh 'foo', 'bar', 'baz';</tt></dt>
		<dd>Print to <tt>$fh</tt>.</dd>
		</dl>
		<p>Special filehandles:</p>
		<dl>
		<dt><tt>STDOUT</tt></dt>
		<dd>Standard output</dd>
		<dt><tt>STDERR</tt></dt>
		<dd>Standard error</dd>
		</dl>
	</body></slide>
</slideshow>
