48
Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

Embed Size (px)

Citation preview

Page 1: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

Llama to RamHow to think like a perl weenie

Rob Napier

3/18/99

Page 2: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 2

Introduction

In this talk we will move from the basics of perl syntax and grammar (Llama) to the philosophy behind perl and the tools of the trade (Ram).

This talk will not cover many advanced perl topics, and in particular won't cover performance issues or advanced data structures

Page 3: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 3

Topics of Discussion

Background and philosophy Perl basics Tools of the trade Pitfalls Perl rules Gotchas

Page 4: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 4

Background and Philosophy

Quotes Influences O’Reilly Bestiary

Page 5: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 5

Quotes

Practical Extraction and Report Language Perl is a language for getting things done. There’s more than one way to do it

Page 6: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 6

Major Influences

C sh regex unix LISP and COBOL

Page 7: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 7

O’Reilly Bestiary

Learning - Llama Programming - Camel Cookbook - Ram Advanced - Leopard/Panther Also Perl/Tk, Nutshell, Win32, and others

Page 8: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 8

Perl Basics

Auto-conversion (coercion) The search for Truth Safety nets Data types

Page 9: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 9

Auto-conversion (coercion)

Strings <=> Numbers References => Strings undef => Strings

Scalars => Lists Lists => Scalar

The dreaded 1’s

Page 10: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 10

The Search for Truth

False: “”, “0”

False = 0, undef, () True = 1, ref, “0 but true”, and most anything else

Page 11: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 11

Safety Nets

-w use strict

Page 12: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 12

Data types

Scalars Lists Hashes Filehandles References

Page 13: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 13

Scalars

Numbers Strings References undef Typeglob Filehandle

$foo = “bar”;

Page 14: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 14

Lists

Heterogeneous Both list-like and array-like, but usually list-like

@foo = qw(bar baz bang);

$bing = @foo[4];

@bang = @foo[4, 6];

Page 15: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 15

Hashes

Associate arrays keys, values, each, delete, exists

%foo = (apple => “red”, orange => “orange”, foo => 2);

$foo{apple} = “orange”;

@foo{apple, orange};

Page 16: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 16

Filehandles

open (FOO, “foo”); while (<FOO>) { while (<>) {

Includes predefined STDOUT, STDIN, STDERR

Page 17: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 17

Typeglobs

Entries in the symbols table Not used very often except for references to

filehandles

Page 18: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 18

References

Hard Symbolic

Page 19: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 19

Hard References

Similar to C-style pointers.

$scalarref = \$foo;

$arrayref = \@ARGV;

$hashref = \%ENV;

$coderef = \&handler;

$globref = \*foo;

$scalarref = \1;

$arrayref = [1, 2, [‘a’, ‘b’, ‘c’]];

$hashref = {‘Adam’ => ‘Eve’, ‘Clyde’ => Bonnie’ };

$coderef = sub {print “Boink!\n” };

Page 20: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 20

Symbolic References

Indirect references to variable These can be very dangerous (and aren’t allowed

under ‘use strict’)

$$scalarref; @$arrayref; %$hashref

Page 21: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 21

Tools of the trade

Lists Hashes Regex Subs Modules

Page 22: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 22

Lists

Usually used as lists, instead of arrays qw() Sets Slurping

Page 23: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 23

Lists, seldom arrays

Usually use foreach, rather than subscripting into arrays. Instead of:

for ($i =0; $i <= $#list; $i++) {

do_something($list[$i]);

}

Do this:

foreach $elem (@list) {

do_something($_);

}

Page 24: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 24

qw()

Very good way to set lists of quoted words:

@foo = qw(this is a test);

Page 25: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 25

Sets

@isect = @diff = @union = ();

foreach $e (@a, @b) { $count{$e}++ }

foreach $e (keys %count) {

push(@union, $e);

push @{ $count{$e} == 2 ? \@isect : \@diff }, $e;

}

Page 26: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 26

Slurping

Often it’s handy to just slurp a whole file and work on it in memory:

open(FOO, “foo”);

@foo = <FOO>;

Page 27: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 27

Hashes

Swiss-army knife of perl Associative arrays Records “In list” applications

Page 28: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 28

Associate Arrays

%foo = (apple => “red”,

orange => “orange”);

print $foo{apple};

Page 29: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 29

Records

The hard way

@entry = getpwuid($<);

%user = (name => $entry[0],

passwd => $entry[1],

uid => $entry[2],

gid => $entry[3],

quota => $entry[4],

comment => $entry[5],

[…],

expire => $entry[9]);

print “name is $user{name}\n”;

Page 30: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 30

Records cont

The easy way (i.e. the perl way)

@fields = qw(name passwd uid gid quota comment gcos dir shell expire);

@user{@fields} = getpwuid $<;

print “name is $user{name}\n”;

Page 31: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 31

“In list” applications

Maintaining list ordersub unique {

my (@list) = (@_);

my %seen = (); # Hash to keep track of what we've seen

my $item; # Current item

my @uniq; # Unique list

foreach $item (@list) {

push (@uniq, $item) unless $seen{$item}++;

}

return @uniq;

}

Page 32: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 32

“In list” applications cont

Trashing list order

sub unique {

my (@list) = (@_)

my %uniq;

@uniq{@list} = ();

return keys @uniq;

}

Page 33: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 33

Regex

Very useful for getting a lot of things done fast.

Rob Napier: 9408 Erinsbrook Drive, Raleigh, NC 27613 (919)848-9523

/(.*):\s*([^,]*),\s*([^,]*),\s*(\w+)\s+(\d+)\s+(?=\()(.*)/

$name = $1;

$address = $2;

$city = $3;

$state = $4;

$zip = $5;

$phone = $6;

Page 34: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 34

Subs

Passing non-scalars Returning non-scalars Named parameters

Page 35: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 35

Passing non-scalars

Try to move non-scalar to the end If you can’t, pass a reference

sub foo {

my @a = @{shift()};

my @b = @{shift()};

print “@a\n”;

print “@b\n”;

}

foo(\@bar, \@baz);

Page 36: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 36

Returning non-scalars

If you can return it as a flat list (or hash), then just return it.

If you have multiple, distinct return values, return a list of references

sub foo {

my @a = qw(this is a test);

my @b = qw(this is a test);

return (\@a, \@b);

}

Page 37: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 37

Named parameters

sub thefunc {

my %args = (

INCREMENT => '10s',

FINISH => 0,

START => 0,

@_, # argument pair list goes here

);

if ($args{INCREMENT} =~ /m$/ ) { ..... }

}

thefunc(INCREMENT => "20s", START => "+5m", FINISH => "+30m");

Page 38: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 38

Modules

File::Path File::Find File::Copy Exporter getop sendmail CGI Cwd

Page 39: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 39

perl4 pitfalls

use strict! (and debatably also use -w) local => my chop => chomp require => use Avoid globals Avoid typeglobs Investigate complex data structures

Page 40: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 40

sh pitfalls

use strict! << instead of multiple prints 0=false, 1=true except on system calls Don’t over-fork. Most of what you want is in perl:

rm/rm -rf, find, ls, echo, grep, awk, sed, pwd, mkdir, mkdir -p, chown, chgrp, cp, ln

Avoid globals

Page 41: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 41

sh pitfalls (cont)

Don’t store lists as strings Avoid temp files Avoid excessive chdir()

Page 42: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 42

C pitfalls

Avoid subscripting lists that you’re iterating over printf -> print Don’t fear labels, especially for using ‘last’ and

‘next’ Don’t try to split a string character by character.

Use regex. Don’t overlook POSIX

Page 43: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 43

General perl pitfalls

Generally you don’t need to add .pl onto script names.

Often readdir() is a better tool than glob() tr/a-z/A-Z/ -> uc()

Page 44: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 44

Perl rules

Always return() Always check your system return codes and close()

returns use strict $# => scalar (or scalar context)

Some people may debate this one, but I find it helps a lot.

Before writing anything complex, always check CPAN (www.cpan.com)

Page 45: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 45

Gotchas

BEGIN { use strict; } There is no real function prototype mechanism

(perl prototypes aren’t what you think) << EOF

Watch out for spaces before the EOF != vs ne, == vs eq, + vs .

number vs. string

Page 46: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 46

Gotchas cont

&&, ||, and, or && and || bind tightly. “and” and “or” bind loosely Generally, you use && and || in boolean logic, while

“and” and “or” are used for “or die” type error checking.

print “@foo” vs print @foo “@foo” adds spaces. This includes inside a HERE-

docs

Page 47: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 47

Gotchas cont

`foo` or warn This only warns if `foo` returns no output (even if

that output is an error) split (‘ ‘, ...)

Splits on whitespace /[ \n\t]+/, not just ‘ ‘.

Page 48: Llama to Ram How to think like a perl weenie Rob Napier 3/18/99

3/18/99 Llama to Ram -- Rob Napier 48

Wrapup

Thinking like a perl weenie means working with the language instead of against it. Even though “there’s more than one way to do it,” many of those ways fail to make good use of the power that perl offers.

The best way to learn to think in perl is to keep trying to make working scripts more perl-like. The best solution is usually the shortest solution that is still readable.