by alba ferrer - @dawnlua
Here's a list of questions every good Perl programmer should be able to answer effectively:
In computer programming, a sigil (/ˈsɪdʒəl/) is a symbol attached to a variable name, showing the variable's datatype or scope, usually a prefix, as in $foo, where $ is the sigil. Sigil, from the Latin sigillum, meaning a "little sign", means a sign or image supposedly having magical power.[1] In 1999 Philip Gwyn adopted the term "to mean the funny character at the front of a Perl variable".
$items[$index]
and @items[$index]
?
my @jogadoras = ('cegonha', 'sol', 'colorada', 'creta', 'lua', 'macaquinha');
say "With \@ we get: @jogadoras[2]";
say "With \$ we get: $jogadoras[2]";
Scalar value @jogadoras[2] better written as $jogadoras[2] at test.pl line 9.
With @ we get: colorada
With $ we get: colorada
@items[$index]
used to be a way to do a single item array slice, but it's not used anymore.
==
and eq
?==
forces the comparison in numeric context
eq
forces the comparison in string context
if ( "gunga" eq "médio" ) {
say "[eq] Gunga and médio are the same type of berimbau";
} else {
say "[eq] Gunga and médio are different types of berimbau";
}
if ( "gunga" == "médio" ) {
say "[==] Gunga and médio are the same type of berimbau";
} else {
say "[==] Gunga and médio are different types of berimbau";
}
[eq] Gunga and médio are different types of berimbau
Argument "médio" isn't numeric in numeric eq (==) at test.pl line 13.
Argument "gunga" isn't numeric in numeric eq (==) at test.pl line 13.
[==] Gunga and médio are the same type of berimbau
DB<1> $berimbau = 'gunga'
DB<2> x int $berimbau
0 0
DB<3> $berimbau = '2gunga'
DB<4> x int $berimbau
0 2
DB<5> $berimbau = 'gunga2'
DB<6> x int $berimbau
0 0
my %berimbaus = (
'gunga' => 'leader',
'médio' => 'invert',
'viola' => 'free style'
);
my @types_of_berimbaus = %berimbaus;
say Dumper @types_of_berimbaus;
$VAR1 = 'médio';
$VAR2 = 'invert';
$VAR3 = 'gunga';
$VAR4 = 'leader';
$VAR5 = 'viola';
$VAR6 = 'free style';
We get a list of key-value pairs. Every pair in the hash becomes two elements in the list.
perldoc -f «keyword»
if «keyword» is a function
perldoc -q «keyword»
if «keyword» is any word, to look it up in the FAQ
Function | Method |
---|---|
Class::Name::function($param) |
$object->method($param)
Class::Name->method
|
Function | Method |
---|---|
Perl will look for it in the current class only | Perl will look for it in the current class, then its parents, then their parents... until stopping or calling AUTOLOAD |
Function | Method |
---|---|
Whatever you pass explicitly | First parameter is always the current object, then whatever you pass explicitly |
local $x
: saves away the old value of the global variable $x and assigns a new value for the duration of the subroutine/scope (and the subroutines called from it).
my $x
: creates a new variable that is visible only in the current subroutine/scope.
our $var = 'global';
sub visible {
print "var has value $var\n";
}
sub dynamic {
local $var = 'local';
visible();
}
sub lexical {
my $var = 'private';
visible();
}
visible();
dynamic();
lexical();
var has value global
var has value local
var has value global
my
Export
package Capoeira;
use Exporter 'import'; # gives you Exporter's import() method directly
@EXPORT_OK = qw(ginga queixada au_sem_maos); # symbols to export on request
Import
use Capoeira qw(ginga queixada);
@INC
: contains the list of places that do
, require
or use
constructs look for their library files.
-I
command line switchesBEWARE!!!
This behavior changes in 5.26, and '.' is not added anymore (security vulnerability)
To load modules from other directories, use the use lib
pragma
use lib '/home/alba/myhobbies/capoeira/lib/';
use Capoeira;
(Award bonus points for knowing how to enable explanations of all error messages encountered)
use diagnostics;
enable diagnostics;
perl jogo.pl 2>diag.out
splain diag.out
Global symbol "$roda" requires explicit package name at jogo.pl line 7 (#1)
(F) You've said "use strict" or "use strict vars", which indicates
that all variables must either be lexically scoped (using "my" or "state"),
declared beforehand using "our", or explicitly qualified to say
which package the global variable is in (using "::").
Global symbol "$roda" requires explicit package name at jogo.pl line 8 (#1)
Execution of jogo.pl aborted due to compilation errors (#1) (#2)
The array is "flattened" and every element becomes a parameter in the function
sub jogar {
my @participantes = shift;
say "As participantes na roda sao " . join(",", @participantes);
}
my @jogadoras = ('cegonha', 'sol', 'colorada', 'creta', 'lua', 'macaquinha');
jogar(@jogadoras);
As participantes na roda sao cegonha
By passing them as references
sub jogar {
my $jogadoras = shift;
my $jogadores = shift;
say "As participantes na roda sao " . join(",", @$jogadoras);
say "Os participantes na roda sao " . join(",", @$jogadores);
}
my @jogadoras = ('cegonha', 'sol', 'colorada', 'creta', 'lua', 'macaquinha');
my @jogadores = ('marujo', 'tarzan', 'socorrista', 'lambarí', 'afogado', 'calado');
jogar(\@jogadoras, \@jogadores);
As participantes na roda sao cegonha,sol,colorada,creta,lua,macaquinha
Os participantes na roda sao marujo,tarzan,socorrista,lambarí,afogado,calado
return;
and return undef;
?
use Data::Dumper;
sub return_nothing {
return;
}
sub return_undef {
return undef;
}
my $res1 = return_nothing();
my $res2 = return_undef();
say Dumper($res1);
say Dumper($res2);
$VAR1 = undef;
$VAR1 = undef;
use Data::Dumper;
sub return_nothing {
return;
}
sub return_undef {
return undef;
}
my @res1 = return_nothing();
my @res2 = return_undef();
say Dumper(\@res1);
say Dumper(\@res2);
$VAR1 = [];
$VAR1 = [
undef
];
alba@aeryn:~/codi/Paws-0.28$ ls
bin dist.ini lib MANIFEST old_t TODO
Changes examples LICENSE META.json README.md TODO_in_branch
cpanfile gen_classes.pl Makefile.PL META.yml t xt
alba@aeryn:~/codi/Paws-0.28/t$ ls
01_load.t 11_client_exceptions_httptiny
02_aws_object.t 11_client_exceptions_lwp
03_aws_default_object.t 11_client_exceptions.t
04_credentials 12_regions.t
04_credentials.t 13_client_connect_errors.t
05_service_calls.t 14_dns_client_errors.t
10_generate_test_cases.pl 15_timeouts.t
10_responses 16_retries.t
10_responses.t lib
11_client_exceptions_furl
With the prove
command
prove - Run tests through a TAP harness.
alba@aeryn:~/codi/Paws-0.28$ prove -l/ -I local/lib/perl5/ t/01_load.t
t/01_load.t .. 1/? Paws::ApiGateway is not stable / supported / entirely developed at /home/alba/codi/Paws-0.28/lib/Paws/ApiGateway.pm line 2, line 1.
t/01_load.t .. 5/? Paws::CloudFront is not stable / supported / entirely developed at /home/alba/codi/Paws-0.28/lib/Paws/CloudFront.pm line 2, line 1.
Paws::CloudSearchDomain is not stable / supported / entirely developed at /home/alba/codi/Paws-0.28/lib/Paws/CloudSearchDomain.pm line 2, line 1.
t/01_load.t .. 15/? Paws::CognitoSync is not stable / supported / entirely developed at /home/alba/codi/Paws-0.28/lib/Paws/CognitoSync.pm line 2, line 1.
t/01_load.t .. 29/? Paws::EFS is not stable / supported / entirely developed at /home/alba/codi/Paws-0.28/lib/Paws/EFS.pm line 2, line 1.
t/01_load.t .. 33/? Paws::ES is not stable / supported / entirely developed at /home/alba/codi/Paws-0.28/lib/Paws/ES.pm line 2, line 1.
t/01_load.t .. 37/? Paws::ElasticTranscoder is not stable / supported / entirely developed at /home/alba/codi/Paws-0.28/lib/Paws/ElasticTranscoder.pm line 2, line 1.
t/01_load.t .. 41/? Paws::Glacier is not stable / supported / entirely developed at /home/alba/codi/Paws-0.28/lib/Paws/Glacier.pm line 2, line 1.
t/01_load.t .. 43/? Paws::IoT is not stable / supported / entirely developed at /home/alba/codi/Paws-0.28/lib/Paws/IoT.pm line 2, line 1.
t/01_load.t .. 46/? Paws::IoTData is not stable / supported / entirely developed at /home/alba/codi/Paws-0.28/lib/Paws/IoTData.pm line 2, line 1.
Paws::Lambda is not stable / supported / entirely developed at /home/alba/codi/Paws-0.28/lib/Paws/Lambda.pm line 2, line 1.
t/01_load.t .. 57/? Paws::Route53 is not stable / supported / entirely developed at /home/alba/codi/Paws-0.28/lib/Paws/Route53.pm line 2, line 1.
t/01_load.t .. 59/? Paws::S3 is not stable / supported / entirely developed at /home/alba/codi/Paws-0.28/lib/Paws/S3.pm line 2, line 1.
t/01_load.t .. ok
All tests successful.
Files=1, Tests=74, 22 wallclock secs ( 0.03 usr 0.00 sys + 21.75 cusr 0.28 csys = 22.06 CPU)
Result: PASS
#cpan
cpan Capoeira::Jogador;
#cpanminus
cpanm Capoeira::Jogador;
#Strawberry Perl
cpan
cpan> install Capoeira::Musica;
#Active Perl
ppm
ppm> install Capoeira::Musica;
#debian-based
apt-get install libcapoeira-roda-perl
#redhat-based
yum install perl-Capoeira-Roda
#cpanfile
requires 'Moose';
requires 'Capoeira::Roda';
requires 'Capoeira::Musica';
requires 'Capoeira::Jogador';
requires 'Capoeira::Roda';
carton install
open(FILE, "</path/to/file.txt")
vs
open(my $fh, "<", "/path/to/file.txt")
FILE
can generate problems if they are overwritten somewhere else
my $filename = shift;
open my $fh, ">$filename" or die "Can't write to '$filename': $!\n";
say $fh "Born to run\nBobbie Jean\nThunder road";
alba@aeryn:~/codi/goodperl$ cat cantigas.txt
No terreiro da fazenda
Malicia e manha
Angola que me leva
Acende o candieiro
Mas que saudade
Deixa o berimbau falar
alba@aeryn:~/codi/goodperl$ perl sing.pl cantigas.txt
alba@aeryn:~/codi/goodperl$ cat cantigas.txt
Born to run
Bobbie Jean
Thunder road
alba@aeryn:~/codi/goodperl$ perl sing.pl '> cantigas.txt'
alba@aeryn:~/codi/goodperl$ cat cantigas.txt
No terreiro da fazenda
Malicia e manha
Angola que me leva
Acende o candieiro
Mas que saudade
Deixa o berimbau falar
Born to run
Bobbie Jean
Thunder road
my $filename = shift;
open my $fh, "$filename" or die "Can't write to '$filename': $!\n";
say $fh "Born to run\nBobbie Jean\nThunder road";
alba@aeryn:~/codi/goodperl$ perl sing.pl 'rm -f cantigas.txt |'
open
my $filename = shift;
open my $fh, '>', $filename or die "Can't write to '$filename': $!";
alba@aeryn:~/codi/goodperl$ perl sing.pl 'touch malicious_cantigas.sh |'
alba@aeryn:~/codi/goodperl$ ls
sing.pl cantigas.txt touch malicious_cantigas.sh |
alba@aeryn:~/codi/goodperl$ cat touch\ malicious_cantigas.sh\ \|
Born to run
Bobbie Jean
Thunder road
(Award bonus points for knowing how to enable automatic detection and reporting of errors)
my $songs = "./cantigas.txt";
my $res = open (my $fh, "<", $songs);
say Dumper($res);
say "$!";
$VAR1 = undef;
No such file or directory
my $songs = "./cantigas.txt";
open (my $fh, "<", $songs) or die "Cannot open file: $!";
alba@aeryn:~/codi/goodperl$ perl sing.pl
Cannot open file: No such file or directory at sing.pl line 6.
use autodie;
my $songs = "./cantigas.txt";
open(my $fh, "<", $songs); # No need to check!
alba@aeryn:~/codi/goodperl$ perl sing.pl
Can't open './cantigas.txt' for reading: 'No such file or directory' at test.pl line 7
eval BLOCK
[...]the code within the BLOCK is parsed only once--at the same time the code surrounding the "eval" itself was parsed--and executed within the context of the current Perl program.
If there is a syntax error or runtime error, or a "die" statement is executed, "eval" returns "undef" in scalar context or an empty list in list context, and $@ is set to the error message.
my @participantes = ('cegonha', 'lambari', 'calado', 'marujo', 'macaquinha');
eval{
die "Not enough people for a roda!" unless (@participantes > 10);
};
say "$@ Let's go for a beer instead" if $@;
Not enough people for a roda! at jogo.pl line 9.
Let's go for a beer instead
for
and with while
?
open (my $fh, '<', 'cantigas.txt') or die "Cannot read file: $!";
while (my $line = <$fh>) {
print "$line";
}
open (my $fh, '<', 'cantigas.txt') or die "Cannot read file: $!";
foreach my $line (<$fh>) {
print "$line";
}
for
will read the whole file and load it in memory
while
will read line by line as the loop iterates
while
is better for big fileswhile
is the way to go for growing files (e.g. live logs)Parameters are kept in the special variable @_
You can handle the parameters by running shift
on @_
(implicit variable in the function)
sub jogar {
my $participantes = shift;
say "As participantes na roda sao " . join(",", @$participantes);
}
my @jogadoras = ('cegonha', 'sol', 'colorada', 'creta', 'lua', 'macaquinha');
jogar(\@jogadoras);
my ($value) = @_;
mean, and what would happen if you removed them?With the parentheses, evaluation is in list context. $value
will get the first element of the @_
array
Without the parentheses, evaluation is in scalar context. $value
will get the number of elements in the @_
array
sub jogar_par {
my ($participantes) = @_;
say $participantes;
}
sub jogar_no_par {
my $participantes = @_;
say $participantes;
}
my @jogadoras = ('cegonha', 'sol', 'colorada', 'creta', 'lua', 'macaquinha');
jogar_par(@jogadoras);
jogar_no_par(@jogadoras);
cegonha
6
new
a builtin function/keyword?No
It's just a convention
With perldoc
perldoc Paws
NAME
Paws - A Perl SDK for AWS (Amazon Web Services) APIs
SYNOPSIS
use Paws;
my $obj = Paws->service('...');
my $res = $obj->MethodCall(Arg1 => $val1, Arg2 => $val2);
print $res->AttributeFromResult;
DESCRIPTION
Paws is an attempt to develop an always up-to-date SDK that covers all possible AWS services.
STATUS
Please consider the SDK is beta quality. The intention of publishing to CPAN is having the community find the SDK, try it, give
feedback, etc. Some services are still not working, and some heavy refactoring will still be done to the internals. The external
interface to SDK users will try to be kept stable, and changes to it should be notified via ChangeLog
SUPPORTED SERVICES
With the values
function
#player-grade
my %graduacoes = (
'cegonha' => 'azul',
'creta' => 'laranja-azul',
'sol' => 'amarela-laranja',
'afogado' => 'amarela',
'lambarí' => 'verde-roxa'
);
for my $corda (values %graduacoes) {
say $corda;
}
laranja-azul
azul
verde-roxa
amarela
amarela-laranja