Perl

$_ is known as the "default input and pattern matching space".
@_ is the list of incoming parameters to a sub. To read the documentations of perl functions use

$ man perlfunc

$ man perlfaq

Hello World!

put the following lines in a file with any name or extension, e.g. myprl
#!/usr/bin/perl
print "Hello, world!\n";

OR

#!/usr/bin/perl
use 5.010;
say "Hello, world!\n";

and go to the terminal (console, shell, etc)
$ perl myperl

OR
you can make the file executable
$ chmode +x myperl
and run it by just calling its name
$ ./myperl
Comment
# Anything after # is a comment

shebang #!: In a Unix-like operating system, the program loader takes the presence of these two characters as an indication that the file is a script, and tries to execute that script using the interpreter specified by the rest of the first line in the file

Use underscores to make long numbers more readable
61_298_040_283_768
0x1377_0B77
0x50_65_72_7C

2**3 : means two to the third (to the power three)

String concatenation done by . (dot) "aa"."nn"
"fred" x 3     is    "fredfredfred"

        "12fred34" * " 3" will be 36 #    something that isn’t a number at all converts to zero.

use warnings; = perl -w
use diagnostics; #show the documentations of the warnings

$ perl -Mdiagnostics ./my_program   #  -M, to load the pragma only when needed instead of editing the source code each time to enable and disable diagnostics:

You could name your program’s three most-important variables $OOO000OOO, $OO00OO00, and $O0O0O0O0O and Perl wouldn’t be bothered—but in that case, please, don’t ask us to maintain your code!

String Interpolation
$meal   = "brontosaurus steak";
$barney = "fred ate a $meal";    # $barney is now "fred ate a brontosaurus steak"
$barney = 'fred ate a ' . $meal; # another way to write that

The variable name will be the longest possible variable name that makes sense at that part of the string.

if Statement
perl doesn't have boolean datatype
• If the value is a number, 0 means false; all other numbers mean true.
• Otherwise, if the value is a string, the empty string ('') means false; all other strings mean true.
• Otherwise (that is, if the value is another kind of scalar than a number or a string), convert it to a number or a string and try again.
This means that undef means false, while all references are true.
There’s one trick hidden in those rules. Because the string '0' is the exact same scalar value as the number 0, Perl has to treat them both the same. That means that the string '0' is the only nonempty string that is false.

Except in cases where it changes the meaning to remove them, parentheses are always optional.

undef
Variables have the special undef value before they are first assigned. If you try to use this “nothing” as a “numeric something,” it acts like zero. If you try to use it as a “string something,” it acts like the empty string. But undef is neither a number nor a string; it’s an entirely separate kind of scalar value.

Read from a Stream(Keyboard)
$text = <STDIN>; #reads a line
chomp($text);  #If a line ends with two or more newlines, chomp removes only one. If there’s no newline, it does nothing.

Use of curly braces for if and while are mandatory.

Arrays
Automatically allocates apace for new indices. If Perl needs to create the intervening elements, it creates them as undef values:

$rocks[0]  = 'bedrock';      # One element...
$rocks[1]  = 'slate';        # another...
$rocks[2]  = 'lava';         # and another...
$rocks[3]  = 'crushed rock'; # and another...
$rocks[99] = 'schist';       # now there are 95 undef elements

index of the last element:  $#rocks  OR @rocks == 2? (in scalar context gives the result which is the size of the list.

To refer to the entire array, use @rocks read it as "all of the" e.g. "all of the rocks"
List literals:  @myArray = (1,2,3,4);   1..5 : this is a range

@myArray=(1,-28,"fred",4,-10..-3, undef);
print $myArray[1];  #prints -28
print "\n";
print $myArray[2];  #prints fred
print "\n";
print $myArray[5];  #prints -9
print "\n";

List assignment:
($fred, $barney, $dino) = ("flintstone", "rubble", undef);
easy swap:  ($fred, $barney) = ($barney, $fred);   if the size of the sides are not equal, extra ones on the right are ignored and on the left are assigned undef

@arr2 = (@myArray, "book");

an array name is replaced by the list it contains. An array doesn’t become an element in the list because these arrays can contain
only scalars, not other arrays.


           @copyArr = @myArray; # copies the list, changing the content of one will not change the other.

Arrays as stacks :
$element = pop(@myArray)  OR pop @myArray
push(@myArray, 0)  OR push @myArray, 0
push @array, @others; # push a list

shift and unshift are just like push and pop, but they perform on the beginning of the array.
Analogous to pop, shift returns undef if given an empty array variable.

Arrays are interpolated in strings like this and their elements will separated by space:
@rocks=("a","b","c");
print "Three rocks are: @rocks.\n";

@fred = qw(eating rocks is wrong);
$fred = "right";               # we are trying to say "this is right[3]"
print "this is $fred[3]\n";    # prints "wrong" using $fred[3]
print "this is ${fred}[3]\n"; # prints "right" (protected by braces)
print "this is $fred"."[3]\n"; # right again (different string)
print "this is $fred\[3]\n"; # right again (backslash hides it)

foreach $temp(@myArray){
  print $temp;
}

What is the value of the control variable after the loop has finished? It’s the same as it was before the loop started. Perl automatically saves and restores the value of the control variable of a foreach loop.

$_ is the default foreach cursor.
             print; # prints $_

@myArray = reverse(@myArray);
@sorted = sort(@myArray);


context
name of an array: In a list context, it gives the list of elements. But in a scalar context, it returns the number of elements in the array

@people = ("a","b","c");
@list = @people; # a list of three people
$n = @people;    # the number 3

In list context, <STDIN> returns all of the remaining lines up to the end of file. Each line is returned as a separate element of the list.

@lines = <STDIN>; # Read all the lines
chomp(@lines);    # discard all the newline characters at the end of each element

OR chomp(@lines = <STDIN>);

qw// or qw{} or qw<> or qw!! or etc will remove white spaces and return a list of strings qw
@names = qw/ fred barney bamm-bamm /; # is the same as @names={"fred", "barney","bamm-bamm"};

Subroutines

sub mySub{
print "Hi\n";
}

&mySub;


Whatever calculation is last performed in a subroutine is automatically also the return value.
sub sum_of_fred_and_barney {
  print "Hey, you called the sum_of_fred_and_barney subroutine!\n";
  $fred + $barney; # That's the return value
}

parameters are stored in an array called @_

Parameter count: Excess parameters are ignored, insufficient parameters filled with undef

my operator will make local variables for any block (foreach, if, subroutine, etc)
my $m; # will make a local variable m

sub max {
  my($m, $n);       #by using parenthesis it makes two local variables
  ($m, $n) = @_;    # give names to the parameters
OR my($m, $n) = @_; # Name the subroutine parameters
  if ($m > $n) {
     $m
  } else {
     $n
   }

}

my($num) = @_; # list context, same as ($num) = @_;
my $num = @_;  # scalar context, same as $num = @_;


If you have two subroutine definitions with the same name, the later one overwrites the earlier one.

return operator returns a value immediately

my @names = qw/ fred barney betty dino wilma pebbles bamm-bamm /;
my $result = &which_element_is("dino", @names);
sub which_element_is {
  my($what, @array) = @_;
  foreach (0..$#array) { # indices of @array's elements
    if ($what eq $array[$_]) {
      return $_;          # return early once found
    }
  }
  −1;                     # element not found (return is optional here)
}

state will allocate persistent variables for a subroutine between calls and does not allocate them again
sub sum {
   state $sum = 0;
   state @numbers;
}

Module

A module should have a .pm extension.

Code View:
(The Me.pm Module)
1   package Me;                     #The same as file name
2   use strict; use warnings;
3   require 5.6;                       # Make sure we're a version of Perl no
                                               # older than 5.6
4   require Exporter;               # Exporter.pm allows symbols to be imported
                                               # by others
5   our @ISA=qw(Exporter);   # ISA is a list of base packages needed
                                                # by this module
6   our @EXPORT_OK=qw(hello goodbye );           # List of your subroutines
                                                                                # to export
7   sub hello { my($name)=shift;
        print "Hi there, $name.\n" };
8   sub goodbye { my($name)=shift;
        print "Good-bye $name.\n";}
9   sub do_nothing { print "Didn't print anything.
                            Not in EXPORT list\n";}
    1;          #mandatory, why?
–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    #!/usr/bin/perl
    # Program name: main.perl
10 use lib ("/home/ellie/Modules");    # A pragma to update @INC.
11 use Me qw(hello goodbye);           # Import package
12 &hello ("Daniel");
13 &goodbye ("Steve");
14  &do_nothing;      # This was not on the Export list
                      # in Me.pm so cannot be imported unless
                      # explicitly with &Me::do_nothing
(Output)
12 Hi there, Daniel.
13 Good-bye Steve.
14 Undefined subroutine &main::do_nothing

Hyphen Command-line Argument: If you give no invocation arguments, the program should process the standard input stream. Or, as a special case, if you give just a hyphen as one of the arguments, that means standard input as well.

Diamond <>   : a special kind of line-input operator. But instead of just getting the input from the keyboard, it comes from the user’s choice of input. it looks for the files with names set in @ARGV otherwise the standard input (keyboard).
tryDiamond.pl
#!/usr/bin/perl
while(<>){
    print $_;
}

$ tryDiamond.pl someFile1.log otherFile
Will print the content of all files proposed as arguments. and prints an error message for those that it cannot find.

$0 is a special variable in perl that holds the name of the executing file itself.

Using parenthesis is optional in most commands and if no argument is set, they will look for $_(in for or while) or @_(in subroutines) for their arguments.

Output
print @array;   # print the list of items, no spacing
print "@array"; # print a string (containing an interpolated array); items separated by space

IO Files

The general idea is that your program should blindly read from STDIN and blindly write to STDOUT, trusting in the user (or generally whichever program is starting your program) to have set those up. In that way, the user can type a command like this one at the shell prompt:

     $ ./your_program <dino >wilma

That command tells the shell that the program’s input should be read from the file dino, and the output should go to the file wilma.
And at no extra charge, the program will work in a pipeline. This is another concept from Unix, which lets us write command lines like this one:

Linux Pipeline Execution

$ cat fred barney | sort | ./your_program | grep something | lpr

This line says that the cat command should print out all of the lines of file fred followed by all of the lines of file barney. Then that output should be the input of the sort command, which sorts those lines and passes them on to your_program. After it has done its processing, your_program will send the data on to grep, which discards certain lines in the data, sending the others on to the lpr command, which should print everything that it gets on a printer. Whew!

Pipelines like that are common in Unix and many other systems today because they let you build powerful, complex commands out of simple, standard building blocks. Each building block does one thing very well, and it’s your job to use them together in the right way.

Also, generally, errors aren’t buffered. That means that if the standard error and standard output streams are both going to the same place (such as the monitor), the errors may appear earlier than the normal output. For example, if your program prints a line of ordinary text, then tries to divide by zero, the output may show the message about dividing by zero first, and the ordinary text second.

Open/Close a Filehandle

there are also six special filehandle names that Perl already uses for its own purposes: STDIN, STDOUT, STDERR, DATA, ARGV, and ARGVOUT.

open CONFIG, "dino"; #input
open CONFIG, "<dino"; #input, suggested for security reasons
open BEDROCK, ">fred"; #output, create, rewrite
open LOG, ">>logfile"; #output, create, append

Check the status of an opnened file:
my $success = open LOG, ">>logfile"; # capture the return value
if ( ! $success) {
  # The open failed 
}

OR
if ( ! open LOG, ">>logfile") {
  die "Cannot create logfile: $!"; # $! is the human-readable complaint from the system.
  # die will automatically append the Perl program name and line number.
}


close BEDROCK;

warn

Reading a file
if ( ! open PASSWD, "/etc/passwd") {
  die "How did you get logged in? ($!)";
}
while (<PASSWD>) {
  chomp;
  ...
}

Special Debug Info
 You might also want to look into the special __FILE__ and __LINE__ tokens (or the caller function

print LOG "Captain's log, stardate 3.14159\n"; # output goes to LOG
printf STDERR "%d percent complete.\n", $done/$total * 100;

send error messages to a file, rather than to your program’s standard error stream
# Send errors to my private error log
if ( ! open STDERR, ">>/home/barney/.error_log") {
  die "Can't open error log for append: $!";
}

backquote (the character along with ~ on the keyboard) executes an external program and return the output as the result.
$cmd= `pwd`

The Smart Match Operator

                 Hash keys identical                                  %a ~~ %b
                 At least one key in %a is in @b               %a ~~ @b
                 At least one key matches pattern              %a ~~ /Fred/
                 Hash key existence exists $a{Fred}           %a ~~ 'Fred'
                 Arrays are the same                                  @a ~~ @b
                 At least one element matches pattern         @a ~~ /Fred/
                 At least one element is 123, numerically     @a ~~ 123
                 At least one element is 'Fred', stringwise    @a ~~ 'Fred'
                 $name is not defined                                $name ~~ undef
                 Pattern match                                          $name ~~ /Fred/
                 Numeric equality with “numish” string         123 ~~ '123.0'
                 String equality                                           'Fred' ~~ 'Fred'
                 Numeric equality                                       123 ~~ 456

eval  Exception Catcher
eval { $barney = $fred / $dino } ;

grep     picking items from a list
my @odd_numbers = grep { $_ % 2 } 1..1000;            #odd numbers
my @matching_lines = grep { /\bfred\b/i } <FILE>;

Slice
my $card_num = (split /:/)[1];
my $count = (split /:/)[5];
my($card_num, $count) = (split /:/)[1, 5];
my($first, $last) = (sort @names)[0, −1];#first last