* New questions and spell check (#181) Added new questions related with KVM, Libvirt and DNF * Create a new perl folder and move the content of the actual section
11 KiB
Perl
Perl Self Assessment
What is Perl?
From the official docs:
"Perl officially stands for Practical Extraction and Report Language, except when it doesn't."
It's a general purpose programming language developed for manipulating texts mainly. It has been used to perform system administration tasks, networking, building websites and more.
What data types Perl has? And how can we define it?
- Scalar: This is a simple variable that stores single data items. It can be a string, number or reference.
my $number = 5;
- Arrays: This is a list of scalars.
my @numbers = (1, 2, 3, 4, 5);
# or using the `qw` keyword (quote word):
my @numbers = qw/1 2 3 4 5/;
# '/' can be another symbol, e.g qw@1 2 3 4 5@
- Hashes (or associative arrays): This is an unordered collection of key-value pairs. We can access to a hash using the keys.
my %numbers = (
First => '1',
Second => '2',
Third => '3'
);
How can you access to a hash value, add and delete a key/value pair and modify a hash?
my %numbers = (
'First' => '1',
'Second' => '2',
'Third' => '3'
);
- Access:
print($numbers{'First'});
- Add:
$numbers{'Fourth'} = 4;
- Delete:
delete $numbers{'Third'};
- Modify:
$numbers{'Fifth'} = 6;
$numbers{'Fifth'} = 5;
How can you iterate an array? And a hash?
- Array:
my @numbers = qw/1 2 3 4 5/;
# Using `$_` that represents the current iteration in a loop. It starts from index array 0 until the last index.
foreach (@numbers) {
print($_);
}
# Output: 12345
# "$#" returns the max index of an array. That's the reason because we can iterate accesing to the array from the index 0 to the max index.
for my $i (0..$#numbers) {
print($numbers[$i]);
}
# Output: 12345
# Using the `map` keyword:
print map {$_} @numbers;
# Output: 12345
# Using `while`. We should take care with this option. When we use `shift` we're deleting the first element of the array and assigning it to the `element` variable.
# After this `loop` the `numbers` array will not have elements.
while (my $element = shift(@numbers)) {
print($element);
}
# Output: 12345
- Hashes:
my %capital_cities = (
'Madrid' => 'Spain',
'Rome' => 'Italy',
'Berlin' => 'Germany'
);
# Iterate and get the `keys`:
foreach my $city (keys %capital_cities) {
print($city . "\n");
}
# Iterate and get the `values`:
foreach my $country (values %capital_cities) {
print($country . "\n");
}
# Iterate and get the values and keys (first option):
foreach my $city (keys %capital_cities) {
print("City: $city - Country: $capital_cities{$city}" . "\n");
}
# Iterate and get the values and keys (first option):
while(my ($city, $country) = each %capital_cities) {
print("City: $city - Country: $capital_cities{$city}" . "\n");
}
What is a Perl subroutine? How to define it?
It's the perl model for user defined functions (this is also called function like other programming languages). We can define a subroute with the keyword sub
.
sub hello {
print "hello";
}
Describe the different ways to receive parameters in a subroutine
- List assignment: Using the
@_
array. It's a list with the elements that are being passed as parameters.
sub power {
my ($b, $e) = @_;
return $b ** $e;
}
&power(2, 3);
- Individual assigment: We should access to every element of the
@_
array. It starts from zero.
sub power {
my $b = $_[0];
my $e = $_[1];
return $b ** $e;
}
&power(2, 3);
- Using
shift
keyword: It's used to remove the first value of an array and it's returned.
sub power {
my $b = shift;
my $3 = shift;
return $b ** $e;
}
&power(2, 3);
We can also read the best way in the same S.O answer.
What is lexical and dynamic scoping?
How to apply referencing and dereferencing?
What is Perl POD? Can you code an example?
From the official docs:
"Pod is a simple-to-use markup language used for writing documentation for Perl, Perl programs, and Perl modules."
=item
This function returns the factorial of a number.
Input: $n (number you wanna calculate).
Output: number factorial.
=cut
sub factorial {
my ($i, $result, $n) = (1, 1, shift);
$result = $result *= $i && $i++ while $i <= $n;
return $result;
}
Perl Regex
Check if the word `electroencefalografista` exists in a string
my $string = "The longest accepted word by RAE is: electroencefalografista";
if ($string =~ /electroencefalografista/) {
print "Match!";
}
Check if the word `electroencefalografista` does not exists in a string
my $string = "The longest not accepted word by RAE is: Ciclopentanoperhidrofenantreno";
if ($string !~ /electroencefalografista/) {
print "Does not match!";
}
Replace the word `amazing`
my $string = "Perl is amazing!";
$string =~ s/amazing/incredible/;
print $string;
# Perl is incredible!
Extract `hh:mm:ss` with capturing group `()` in the following datetime
my $date = "Fri Nov 19 20:09:37 CET 2021";
my @matches = $date =~ /(.*)(\d{2}:\d{2}:\d{2})(.*)/;
print $matches[1];
# Output: 20:09:37
Extract all the elements that are numbers in an array
my @array = ('a', 1, 'b', 2, 'c', 3);
my @numbers = grep (/\d/, @array); # Note: \d involves more digits than 0-9
map {print $_ . "\n" } @numbers;
Print all the linux system users that starts with d or D
- With a Perl one liner :D
open(my $fh, '<', '/etc/passwd');
my @user_info = <$fh>;
map { print $& . "\n" if $_ =~ /^d([^:]*)/ } @user_info;
close $fh;
- Avoiding one-liners
foreach my $user_line (@user_info) {
if ($user_line =~ /^d([^:]*)/) {
print $& . "\n";
}
}
Perl Files Handle
Mention the different modes in File Handling
- Read only:
<
- Write mode. It creates the file if doesn't exist:
>
- Append mode. It creates the file if doesn't exist:
>>
- Read and write mode:
+<
- Read, clear and write mode. It creates the file if doesn't exist:
+>
- Read and append. It creates the file if doesn't exist:
+>>
How to write into a file?
# We can use:
# '>' Write (it clears a previous content if exists).
# '>>' Append.
open(my $fh, '>>', 'file_name.ext') or die "Error: file can't be opened";
print $fh "writing text...\n";
close($fh);
How can you read a file and print every line?
open(my $fh, '<', 'file_to_read.ext') or die "Error: file can't be opened";
my @file = <$fh>;
foreach my $line (@file) {
print $line;
}
We can use the file handle without assigning it to an array:
open(my $fh, '<', 'file_to_read.ext') or die "Error: file can't be opened";
foreach my $line (<$fh>) {
print $line;
}
Perl OOP
Does Perl have support for OOP?
From the official docs:
"By default, Perl's built-in OO system is very minimal, leaving you to do most of the work."
What is the purpose of the bless function?
The function os the bless
function is used to turning a plain data structure into an object.
How to create a Perl class? How can you call a method?
- Let's create the package:
Example.pm
package Example;
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
return $self;
}
sub is_working {
print "Working!";
}
1;
- Now we can instance the
Example
class and callis_working
method:
my $e = new Example();
$e->is_working();
# Output: Working!
Does Perl have inheritance? What is the `SUPER` keyword?
Yes, Perl supports inheritance. We can read about it in the official docs.
We also can read about SUPER
keyword that is used to call a method from the parent class. It gives an example about how we can apply inheritance.
Does Perl have polymorphism? What is method overriding?
Yes, it has polymorphism. In fact method overriding is a way to apply it in Perl.
Method overriding in simple words appears when we have a class with a method that already exist in a parent class.
Example:
package A;
sub new { return bless {}, shift; };
sub printMethod { print "A\n"; };
package B;
use parent -norequire, 'A';
sub new { return bless {}, shift; };
sub printMethod { print "B\n"; };
my $a = A->new();
my $b = B->new();
A->new()->printMethod();
B->new()->printMethod();
# Output:
# A
# B
How can you call a method of an inherited class?
# Class `A` with `printA` method.
package A;
sub new { return bless {}, shift; };
sub printA { print "A"; };
# Class `B` that extends or use the parent class `A`.
package B;
use parent -norequire, 'A';
sub new { return bless {}, shift; };
# Instance class `B` allows call the inherated method
my $b = B->new();
$b->printA();