Perl - Subrutin

Sebuah subrutin atau fungsi Perl adalah sekelompok pernyataan yang bersama-sama melakukan tugas. Anda dapat membagi kode Anda menjadi subrutin yang terpisah. Bagaimana Anda membagi kode Anda di antara subrutin yang berbeda terserah Anda, tetapi secara logis pembagian biasanya dilakukan sehingga setiap fungsi melakukan tugas tertentu.

Perl menggunakan istilah subrutin, metode dan fungsi secara bergantian.

Tentukan dan Panggil Subrutin

Bentuk umum dari definisi subrutin dalam bahasa pemrograman Perl adalah sebagai berikut -

sub subroutine_name {
   body of the subroutine
}

Cara umum untuk memanggil subrutin Perl adalah sebagai berikut -

subroutine_name( list of arguments );

Dalam versi Perl sebelum 5.0, sintaks untuk memanggil subrutin sedikit berbeda seperti yang ditunjukkan di bawah ini. Ini masih berfungsi di versi terbaru Perl, tetapi tidak disarankan karena ia melewati prototipe subrutin.

&subroutine_name( list of arguments );

Mari kita lihat contoh berikut, yang mendefinisikan sebuah fungsi sederhana dan kemudian memanggilnya. Karena Perl mengkompilasi program Anda sebelum menjalankannya, tidak masalah di mana Anda mendeklarasikan subrutin Anda.

#!/usr/bin/perl

# Function definition
sub Hello {
   print "Hello, World!\n";
}

# Function call
Hello();

Ketika program di atas dijalankan, itu menghasilkan hasil sebagai berikut -

Hello, World!

Meneruskan Argumen ke Subrutin

Anda dapat meneruskan berbagai argumen ke subrutin seperti yang Anda lakukan dalam bahasa pemrograman lain dan argumen tersebut dapat diakses di dalam fungsi menggunakan larik khusus @_. Jadi argumen pertama untuk fungsi tersebut adalah di $ _ [0], yang kedua di $ _ [1], dan seterusnya.

Anda dapat meneruskan array dan hash sebagai argumen seperti skalar apa pun, tetapi meneruskan lebih dari satu array atau hash biasanya menyebabkan mereka kehilangan identitas terpisahnya. Jadi kita akan menggunakan referensi (dijelaskan di bab berikutnya) untuk melewatkan array atau hash apa pun.

Mari kita coba contoh berikut, yang mengambil daftar angka dan kemudian mencetak rata-ratanya -

#!/usr/bin/perl

# Function definition
sub Average {
   # get total number of arguments passed.
   $n = scalar(@_);
   $sum = 0;

   foreach $item (@_) {
      $sum += $item;
   }
   $average = $sum / $n;

   print "Average for the given numbers : $average\n";
}

# Function call
Average(10, 20, 30);

Ketika program di atas dijalankan, itu menghasilkan hasil sebagai berikut -

Average for the given numbers : 20

Meneruskan Daftar ke Subrutin

Karena variabel @_ adalah larik, ia dapat digunakan untuk menyediakan daftar ke subrutin. Namun, karena cara Perl menerima dan mem-parsing daftar dan array, akan sulit untuk mengekstrak elemen individu dari @_. Jika Anda harus meneruskan list bersama dengan argumen skalar lainnya, maka jadikan list sebagai argumen terakhir seperti yang ditunjukkan di bawah ini -

#!/usr/bin/perl

# Function definition
sub PrintList {
   my @list = @_;
   print "Given list is @list\n";
}
$a = 10;
@b = (1, 2, 3, 4);

# Function call with list parameter
PrintList($a, @b);

Ketika program di atas dijalankan, itu menghasilkan hasil sebagai berikut -

Given list is 10 1 2 3 4

Meneruskan Hash ke Subrutin

Saat Anda memberikan hash ke subrutin atau operator yang menerima daftar, hash secara otomatis diterjemahkan ke dalam daftar pasangan kunci / nilai. Misalnya -

#!/usr/bin/perl

# Function definition
sub PrintHash {
   my (%hash) = @_;

   foreach my $key ( keys %hash ) {
      my $value = $hash{$key};
      print "$key : $value\n";
   }
}
%hash = ('name' => 'Tom', 'age' => 19);

# Function call with hash parameter
PrintHash(%hash);

Ketika program di atas dijalankan, itu menghasilkan hasil sebagai berikut -

name : Tom
age : 19

Mengembalikan Nilai dari Subrutin

Anda dapat mengembalikan nilai dari subrutin seperti yang Anda lakukan dalam bahasa pemrograman lainnya. Jika Anda tidak mengembalikan nilai dari subrutin maka perhitungan apa pun yang terakhir dilakukan dalam subrutin secara otomatis juga merupakan nilai kembalian.

Anda dapat mengembalikan array dan hash dari subrutin seperti skalar lainnya, tetapi mengembalikan lebih dari satu array atau hash biasanya menyebabkan mereka kehilangan identitas yang terpisah. Jadi kita akan menggunakan referensi (dijelaskan di bab berikutnya) untuk mengembalikan larik atau hash apa pun dari suatu fungsi.

Mari kita coba contoh berikut, yang mengambil daftar angka dan kemudian mengembalikan rata-ratanya -

#!/usr/bin/perl

# Function definition
sub Average {
   # get total number of arguments passed.
   $n = scalar(@_);
   $sum = 0;

   foreach $item (@_) {
      $sum += $item;
   }
   $average = $sum / $n;

   return $average;
}

# Function call
$num = Average(10, 20, 30);
print "Average for the given numbers : $num\n";

Ketika program di atas dijalankan, itu menghasilkan hasil sebagai berikut -

Average for the given numbers : 20

Variabel Privat dalam Subrutin

Secara default, semua variabel di Perl adalah variabel global, yang berarti variabel dapat diakses dari mana saja dalam program. Tapi Anda bisa membuatnyaprivate variabel yang disebut lexical variables kapan saja dengan my operator.

Itu myoperator membatasi variabel ke wilayah kode tertentu yang dapat digunakan dan diakses. Di luar kawasan itu, variabel ini tidak dapat digunakan atau diakses. Wilayah ini disebut ruang lingkupnya. Cakupan leksikal biasanya merupakan blok kode dengan sekumpulan kurung kurawal di sekitarnya, seperti yang mendefinisikan badan subrutin atau yang menandai blok kode dari pernyataan if, while, for, foreach, dan eval .

Berikut adalah contoh yang menunjukkan kepada Anda bagaimana mendefinisikan satu atau beberapa variabel privat menggunakan my operator -

sub somefunc {
   my $variable; # $variable is invisible outside somefunc()
   my ($another, @an_array, %a_hash); # declaring many variables at once
}

Mari kita periksa contoh berikut untuk membedakan antara variabel global dan privat -

#!/usr/bin/perl

# Global variable
$string = "Hello, World!";

# Function definition
sub PrintHello {
   # Private variable for PrintHello function
   my $string;
   $string = "Hello, Perl!";
   print "Inside the function $string\n";
}
# Function call
PrintHello();
print "Outside the function $string\n";

Ketika program di atas dijalankan, itu menghasilkan hasil sebagai berikut -

Inside the function Hello, Perl!
Outside the function Hello, World!

Nilai Sementara melalui local ()

Itu localbanyak digunakan ketika nilai variabel saat ini harus terlihat oleh subrutin. Lokal hanya memberikan nilai sementara untuk variabel global (artinya paket). Ini dikenal sebagai pelingkupan dinamis . Scoping leksikal dilakukan dengan my, yang bekerja lebih seperti deklarasi otomatis C.

Jika lebih dari satu variabel atau ekspresi diberikan ke lokal, mereka harus ditempatkan dalam tanda kurung. Operator ini bekerja dengan menyimpan nilai saat ini dari variabel tersebut dalam daftar argumennya di tumpukan tersembunyi dan memulihkannya setelah keluar dari blok, subrutin, atau eval.

Mari kita periksa contoh berikut untuk membedakan antara variabel global dan lokal -

#!/usr/bin/perl

# Global variable
$string = "Hello, World!";

sub PrintHello {
   # Private variable for PrintHello function
   local $string;
   $string = "Hello, Perl!";
   PrintMe();
   print "Inside the function PrintHello $string\n";
}
sub PrintMe {
   print "Inside the function PrintMe $string\n";
}

# Function call
PrintHello();
print "Outside the function $string\n";

Ketika program di atas dijalankan, itu menghasilkan hasil sebagai berikut -

Inside the function PrintMe Hello, Perl!
Inside the function PrintHello Hello, Perl!
Outside the function Hello, World!

Variabel Status melalui state ()

Ada tipe lain dari variabel leksikal, yang mirip dengan variabel privat tetapi mereka mempertahankan statusnya dan mereka tidak diinisialisasi ulang pada beberapa panggilan subrutin. Variabel ini ditentukan menggunakanstate operator dan tersedia mulai dari Perl 5.9.4.

Mari kita periksa contoh berikut untuk mendemonstrasikan penggunaan state variabel -

#!/usr/bin/perl

use feature 'state';

sub PrintCount {
   state $count = 0; # initial value

   print "Value of counter is $count\n";
   $count++;
}

for (1..5) {
   PrintCount();
}

Ketika program di atas dijalankan, itu menghasilkan hasil sebagai berikut -

Value of counter is 0
Value of counter is 1
Value of counter is 2
Value of counter is 3
Value of counter is 4

Sebelum Perl 5.10, Anda harus menulisnya seperti ini -

#!/usr/bin/perl

{
   my $count = 0; # initial value

   sub PrintCount {
      print "Value of counter is $count\n";
      $count++;
   }
}

for (1..5) {
   PrintCount();
}

Konteks Panggilan Subrutin

Konteks subrutin atau pernyataan didefinisikan sebagai jenis nilai kembali yang diharapkan. Ini memungkinkan Anda menggunakan satu fungsi yang mengembalikan nilai berbeda berdasarkan apa yang diharapkan pengguna untuk diterima. Misalnya, localtime () berikut mengembalikan string saat dipanggil dalam konteks skalar, tetapi mengembalikan daftar saat dipanggil dalam konteks daftar.

my $datestring = localtime( time );

Dalam contoh ini, nilai $ timestr sekarang menjadi string yang terdiri dari tanggal dan waktu saat ini, misalnya, Kam 30 Nov 15:21:33 2000. Sebaliknya -

($sec,$min,$hour,$mday,$mon, $year,$wday,$yday,$isdst) = localtime(time);

Sekarang variabel individu berisi nilai terkait yang dikembalikan oleh subrutin localtime ().