From Wikipedia, the free encyclopedia
[edit] perl notes
[edit] Programming Style
- Do not use "package::foo();" directly. Must use objects. Using package::foo() is non-object.
-
- Even if the object is only used once "$::g_res = new Objx();"
- Always create a main() subroutine to avoid global conflicts.
use Fcntl ':mode';
($dum,$dum,$mode,$dum,$dum,$dum,$dum,$size,$dum,$mtime)=stat($fname);
$mode = S_IMODE($mode)
- "my" is local to the loop/block (not only on the function level).
delete($h{abc}); # deleted
$h{abc}=(); # assign undef to element "abc". "abc" still exist.
$h{abc}=undef; # same as $h{abc}=();
-e Exist
-w Writable
-x Executable
- Avoiding Greedy Expressions
if($line=~/(a.*?b)/) { }
my %hcopy = %{$john->{h}}; # This is not a reference. Performs a deep copy.
my $hr=\%hh; # This is a reference. Same as: $hr={ key=>val, key1=>val1, };
${$hr}{key}="new"; # same as $hh{key}
$rec = {
TEXT => $string,
ARY => [ @aryvariable ],
LOOKUP => { %some_table },
THATCODE => \&some_function,
THISCODE => sub { ....code.... },
HANDLE => \*STDOUT,
}
# Accessing the hash
foreach $k (keys(%{$rec->{LOOKUP}})) { };
print( $rec->{TEXT} );
print( ${$rec}{TEXT} ); # same as above
# Function reference
$rec->{THATCODE}(); # Call some_function()
$rec->{THISCODE}(); # Call the anonymous function
$rf = \&some_function;
&$rf();
String: sort( { $a cmp $b } @arr ); # just reverse $a and $b for reverse. Default is string.
Numeric: sort( { $b <=> $a } @arr );
sort by keys: sort( keys( %hh ));
sort by values (return the keys):
sort( { $hh{$a} <=> $hh{$b} } keys(%hh) );
[edit] Modules
use File::Basename;
$fname = &File::Basename::basename($path);
$dirname = &File::Basename::dirname($path);
use Cwd;
print cwd();
[edit] Goodie Stuff
# Put this at top of file
$SIG{__WARN__} = sub { for ($_[0]) { &process_warn_subr; } }; # trap uninitialized values
.....
# die out if uninitialized warning happens
sub process_warn_subr {
package process_warn_subr;
my @c = caller(1);
if(/Use of uninitialized value/i) {
print "ERROR: perl uninitialized value access detected in $0:\n";
print "-e- => package: $c[0]\n";
print "-e- => file : $c[1]\n";
print "-e- => line : $c[2]\n";
;# promote warning to a fatal version
die "-e- => trap: $_";
} else {
;# other warning cases to catch go here
warn "-w- => trap: $_";
}
}
# Put this at top of file
$SIG{'INT'} = 'dokill'; # or "= sub { }" also works
....
sub dokill {
die("Ctrl+C happened\n\n"); # pressing ctrl+c while inside dokill() has no effect.
} # NOTE: All DESTROY object routines are called here.
[edit] Objects
use Person;
my $john=new Person("John", "Male");
print Person::direct()."\n"; # Access "static" methods directly
print $john->{NAME}."\n"; # Retrieves the {NAME} property.
print $john->name."\n"; # Calls the name() method. $john->name() is the same
print @{$john->array}; # Array access
print %{$john->hash}; # Hash access
$john=(); # calls the destructor.
package Data;
sub new {
my ($class)=@_;
my $this = {};
bless($this, $class);
my $hs = {};
$hs->{data1}=33; # information hash
$hs->{data2}=35;
$this->{dd}=$hs; # Assign it
$this->{tag}="TAG";
return($this);
}
package UserObject;
sub new {
my ($class)=@_;
my $this = {};
bless($this, $class);
$this->{obj} = new Data();
my $all = $this->{obj}->{dd}; # Access the hash of the Data object
my $line;
foreach $line (keys(%{$all})) { # Reference way
print "$line ${$all}{$line}\n";
${$ali}{$line}+=100; # increment it
}
foreach $line (keys(%{$this->{obj}->{dd}})) { # Direct way
print "$line ".${$this->{obj}->{dd}}{$line}."\n"; # Incremented value is seen here
}
return($this);
}
[edit] Object Template
# =============================================================
# OBJECT template
# =============================================================
use strict;
package Person;
# Constructor
sub new {
my ($class, $name, $sx)=@_; # 1st arg is always the classname ($class=="Person")
my $this = {};
bless($this, $class);
$this->{NAME} = $name || (); # Property
$this->{AGE} = 3;
$this->{SEX} = $sx; # same as $$this{SEX}, $this->{SEX}
return($this);
}
# Methods
sub peers {
my($this, @peer) = @_;
# alias all properties to be used
my $PEER = \@{$this->{PEER}};
my $SEX = \$this->{SEX};
my $HH = \%{$this->{hh}}; # Access by ${$HH}{...}
my $AA = \@{$this->{ary}}; # Access by $$AA[..]
$this->SUPER::method(); # to access the base method
if($#peer>=0) {
push(@{$$PEER}, @peer);
}
return($$PEER);
}
sub direct { # Can be accessed from main directly via: Person::direct(). However, don't call methods directly! (violation to programming style)
return($static_sex);
}
sub DESTROY {
print("I'm doing destructor\n");
# NOTE: DESTROY is not called if ctrl+C happened. Add the following line in the constructor:
# $SIG{'INT'} = sub { die("Ctrl+C happened\n\n"); } ; # This is necessary for DESTROY to be called even if Ctrl+C
}
# =============================================================
# Inheritance template
# =============================================================
use strict;
package Person2;
use obj; # The base obj. Remove this if the base obj is on the same file
use vars qw(@ISA);
@ISA = ("Person"); # inherits from Person
# Constructor
sub new { # ok to inherit as long as it is not on main file.
my ($class, $n, $s, $job)=@_; # 1st arg is always the classname
my $this = new Person($n, $s); # same as $class->Person::new($n, $s);
bless($this, $class);
..... # e.g. $$JOB = $job;
return($this);
}
; # override any methods that needed to be overridden...
[edit] Benchmarks
- invoking perl: 1000 system call to perl:
Windows: 93ms per perl invoke (via system)
Windows: 43ms per touch invoke (via system)
UNIX: 40ms per perl invoke