Monday, March 31, 2014

some basic perl syntax

1) file operation
#read a file
open FH, "< $filename" or die "Cannot open file $filename: $!\n";
open FH, "$filename" or die "Cannot open file $filename: $!\n";
#write a file
open FH, "> $filename" or die "Cannot open file $filename: $!\n";
#append a file
open FH, ">> $filename" or die "Cannot open file $filename: $!\n";

2) variable definition
the scope of the definition of my is in block
my $var;
the scope of the definition of our is in package
our $var;

3) argument
@ARGV has all the arguments passed by the cmd
$#ARGV shows the number of arguments, if the number is 0, it will show -1
e.g.:
if ($#ARGV >= 0 && $ARGV[0] eq "-d") {
  shift;
  $local_dns = shift;
}

4) call system command
system "ls"
`ls`

5) hash
my %hash1;
$hash1{"m1"} = "a10";
$hash1{"m2"} = "a20";
foreach my $key (keys %hash1) {
    print "$key: $hash1{$key}\n";
}
my @keys = keys %hash1;
#number of keys - 1
print $#keys."\n";
#number of keys
print @keys."\n";

my %hash2 = ("n1" => "b11", "n2" => "b21");
foreach my $value (values %hash1) {
    print "$value\n";
}

my %hash3 = ("o1", "c12", "o2", "c22");
while(my($key, $value) = each %hash2) {
    print "$key: $value\n";
}

6) multi-dimension hash
my $hash_ptr;
$hash_ptr->{UBUNTU}->{NAME} = "Ubuntu";
$hash_ptr->{UBUNTU}->{TYPE} = "Linux";
$hash_ptr->{SOLARIS}->{NAME} = "Solaris";
$hash_ptr->{SOLARIS}->{TYPE} = "Unix";

foreach my $key (keys %{$hash_ptr}) {
    print "OS  : $hash_ptr->{$key}->{NAME}\n";
    print "Type: $hash_ptr->{$key}->{TYPE}\n";
}

my %hash4;
$hash4{UBUNTU}->{NAME} = "Ubuntu";
$hash4{UBUNTU}->{TYPE} = "Linux";
$hash4{SOLARIS}->{NAME} = "Solaris";
$hash4{SOLARIS}->{TYPE} = "Unix";

foreach my $key (keys %hash4) {
    print "OS  : $hash4{$key}->{NAME}\n";
    print "Type: $hash4{$key}->{TYPE}\n";
}

7) array
my @array1;
$array1[0] = "a10";
$array1[1] = "a20";
foreach my $data (@array1) {
    print "$data\n";
}
#number of keys - 1
print $#array1."\n";
#number of keys
print @array1."\n";
if(@array1 == 2) {
    print "\@array1 number is 2\n";
}

my @array2 = ("b11", "b21");
foreach my $data (@array2) {
    print "$data\n";
}

8) argument
my $run_opt;
while(my $switch = shift(@ARGV)) {
    if($switch =~ /^-f$/) {
        $run_opt->{FILE} = shift(@ARGV);
    } elsif($switch =~ /^-keep$/) {
        $run_opt->{KEEP_RESULT} = 1;
    } elsif($switch =~ /^-cov$/) {
        $run_opt->{RUN_WITH_COV} = 1;
        $run_opt->{COV_OPT} = shift(@ARGV);
    } else {
        if(defined($run_opt->{ARG})) {
            $run_opt->{ARG} .= " ".$switch;
        } else {
            $run_opt->{ARG} = $switch;
        }
    }
}

foreach my $key (keys %{$run_opt}) {
    print "key: $key; value: $run_opt->{$key}\n";
}

9) argument: use Getopt::Long
use Getopt::Long;
my $run_opt;
GetOptions (
    "run_time=i" => \$run_opt->{RUN_TIME},
    "f=s"        => \$run_opt->{FILE},
    #will add 1 foreach -keep
    "keep+"      => \$run_opt->{KEEP_RESULT},
    #will be 1 if there is -cov and it does not care how many -cov
    "cov!"       => \$run_opt->{RUN_WITH_COV},
    "cov_opt=s"  => \$run_opt->{COV_OPT},
    "verbose"    => \$run_opt->{VERBOSE}
);

foreach my $key (keys %{$run_opt}) {
    print "key: $key; value: $run_opt->{$key}\n";
}

10) OOP
main.pl:
#!/usr/bin/perl

#either @INC or lib can work
#but @INC must be put in BEGIN{}
BEGIN {
    push @INC, "./class";
}
#use lib "./class";

use rectangle;
use strict;

my $rect = new rectangle(2, 3);
my $length = $rect->getLength();
my $width = $rect->getWidth();
print "Length: $length, Width: $width\n";
undef $rect;

use cube;

my $cube1 = new cube(2, 3, 4);
$length = $cube1->getLength();
$width = $cube1->getWidth();
my $height = $cube1->getHeight();
print "Length: $length, Width: $width, Height: $height\n";

rectangle.pm:
#!/usr/bin/perl
package rectangle;

sub new {
    my $class = shift;
    my $self = {
        length => shift,
        width => shift
    };

    print "rectangle::new called\n";
    print "Length: $self->{length}\n";
    print "Width: $self->{width}\n";

    bless $self, $class;
    return $self;
}

sub DESTROY {
   print "rectangle::DESTROY called\n";
}

sub setLength {
    my($self, $length) = @_;
    $self->{length} = $length;
}

sub getLength {
    my($self) = @_;
    return $self->{length};
}

sub setWidth {
    my($self, $width) = @_;
    $self->{width} = $width;
}

sub getWidth {
    my($self) = @_;
    return $self->{width};
}

1;

cube.pm:
#!/usr/bin/perl

package cube;
use rectangle;
our @ISA = qw(rectangle);    # inherits from Person

# Override constructor
sub new {
    my ($class) = @_;
    #my ($class) = $_[0];

    my $self = $class->SUPER::new($_[1], $_[2]);
    $self->{height} = $_[3];

    print "cube::new called\n";
    print "Height: $self->{height}\n";

    bless $self, $class;
    return $self;
}

sub DESTROY {
    my($self) = @_;
    $self->SUPER::DESTROY;
    print "cube::DESTROY called\n";
}

sub setHeight {
    my($self, $height) = @_;
    $self->{height} = $height;
}

sub getHeight {
    my($self) = @_;
    return $self->{height};
}

1;

11) pack and unpack
pack is used to convert a value to a string and unpack is used to convert a string to a value.

The following example use pack and unpack to change binary data to hex data.
run cmd: ./pack_unpack_test.pl data

data_orig:
#opcode rs    rt    immd
010001  00000 00001 0000 0010 0100 0000
010001  00001 00010 0000 0001 0010 0100
#opcode rs    rt    rd    shamt funct
000001  00001 00010 00000 00000 000000
#opcode offset
000001  00 0000 0000 0000 0000 0000 0010

data:
44010240
44220124
04220000
04000002

pack_unpack_test.pl:
#!/usr/bin/perl

my $out_file = "data_init";

die "Too many arguments\n" if(@ARGV > 1);
while(@ARGV) {
    $arg = shift @ARGV;
    $out_file = $arg;
}

my $in_file = $out_file."_orig";

open FH, "< $in_file" or die "Cannot open file $file: $!\n";
open FOUT, "> $out_file" or die "Cannot open file $file1: $!\n";

while(<FH>) {
    chomp;
    s/^\s+//;
    s/\s+$//;

    next if(/^#/);
    next if(/^\/\//);

    s/\s+//g;

    my $data = unpack("H8", pack("B32", substr("0" x 32 . $_, -32)));
    print FOUT "$data\n";
}

close(FH);
close(FOUT);

101) call external command and send the result to pipe and receive it in perl handler:
open (DIG, "dig \@208.67.222.222 208.67.222.222|") or die "can't open pipe to dig: $!\n";
while(<DIG>) {
    chomp;
    print $_."\n";
}
close DIG;

102) install perl through CPAN
In terminal, run: perl -MCPAN -e shell

No comments:

Post a Comment