Home Map Index Search News Archives Links About LF
[Top bar]
[Bottom bar]
[Photo of the Author]
by Guido Socher

Yazar hakk�nda:

Guido uzun zamand�r bir Linux ba��ml�s� ve Perl korsan�d�r. Bu g�nlerde evini yenilemek ve bah�esinde bitki yeti�tirmekle olduk�a me�guld�r.

��erik:

Perl k�s�m II

[Illustration]

Abstract:

Perl k�s�m I Perl hakk�nda genel bir bak�� sa�lar. Perl k�s�m II'de ilk kullan��l� program�m�z� yazaca��z.



 

Program�n�z i�in bir �at�

Perl en iyi bir soru �zerine �zelle�tirilmi� k���k progromlar yazmakta kulllan�l�r. Geli�tirme i�lemini h�zland�rmak i�in bir �ok programda olmas�n� isteyebilece�iniz temel yap� ve fonksiyon �neren bir �at�y� elde tutmak iyi bir fikir. A�a��daki kod templatetemel komut okuma sat�r� se�ene�i �nerir ve yard�m mesaj� yazd�rmak i�in bir de�i�meze sahiptir.

!/usr/bin/perl -w
# vim: set sw=8 ts=8 si et:
#
# uncomment strict to make the perl compiler very
# strict about declarations:
#use strict;
# global variables:
use vars qw($opt_h);
use Getopt::Std;
#
&getopts("h")||die "ERROR: No such option. -h for help\n";
&help if ($opt_h);
#
#>>your code<<
#
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
sub help{
print "help message\n";
exit;
}
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
__END__

Kaynak koda bir bakal�m. &getopts() komu sat�r� opsiyonunu okumak i�in Getopt::Std k�t�phanesinden bir subroutine �a��r�r. Komut sat�r�nda sa�lanan opsiyonlara g�re $opt_<option> ismi de�i�kenlik g�sterir. Komut sat�r�ndaki b�t�n opsiyonlar "-" (eksi i�areti) ile ba�lar ve program isminden hemen sonra ve ba�ka arg�man girmeden hemen �nce gelmelidir. (Not: bu genel bir Unix kural�d�r). amp;getopts (yukar�daki programdaki "h") komut dizisi izin verilen b�t�n opsiyon harflerini listeler. E�er opsiyon bir arg�man al�rsa o zaman opsiyon harfinden sonra iki nokta �st�ste konulmal�. &getsopt("d:x:h"), bu program -d, -x and -h opsiyonlar�na sahiptir demektir. -d ve -x opsiyonlar� bir arg�man al�rlar. Bu y�zden "-d bir�ey" do�ru olur ama "-d -x bir�ey" -d'yi bir arg�man izlemedi�i i�in yanl�� olur.
E�er komut sat�r�nca -h opsiyonu verilmi�se, $opt_h de�i�keni kurulur ve &help if ($opt_h);sonu�ta e�er -h opsiyonu komut sat�r�nda verilmi�se de�i�mez help'i �a��r�r. sub help{ c�mlesi de�i�mezli�i a��klar. �u anda kodun her detay�n� anlaman�z �ok �nemli de�il. Sadece sizin as�l fonksiyonunuzu ekleyebilece�iniz bir yer olan template olarak anlay�n yeter.

 

Template kullan�m�

�imdi bu �at�y� kullanan k���k bir say� �evirici yazal�m. Program, ona numconv diyelim, alt�l�k say�y� ondal�k say�ya �evirmeli veya tersini yapmal�.
numconv -x 30 ondal�k 30'un alt�l�k dengini yazd�r�r.
numconv -d 1A alt�l�k 1A'n�n ondal�k dengini yazd�r�r.
numconv -h yard�m metini yazd�r�r.
Perl fonksiyonu hex() alt�l�k say�lar� ondal�k say�lara �evirir ve fonksiyon printf() ondal�k say�lar� alt�l�k say�lara �evirmekte kullan�labilir. Bunu template'imize koymak bize g�zel bir program olu�turur:

#!/usr/bin/perl -w
# vim: set sw=8 ts=8 si et:
#
# uncomment strict to make the perl compiler very
# strict about declarations:
#use strict;
# global variables:
use vars qw($opt_d $opt_x $opt_h);
use Getopt::Std;
#
&getopts("d:x:h")||die "ERROR: No such option. -h for help\n";
&help if ($opt_h);
if ($opt_d && $opt_x){
    die "ERROR: options -x and -d are mutual exclusive.\n";
}
if ($opt_d){
    printf("decimal: %d\n",hex($opt_d));
}elsif ($opt_x){
    printf("hex: %X\n",$opt_x);
}else{
    # wrong usage -d or -x must be given:
    &help;
}
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
sub help{
    print "convert a number to hex or dec.
USAGE: numconv [-h] -d hexnum
    umconv [-h] -x decnum

OPTIONS: -h this help
EXAMPLE: numconv -d 1af
\n";
    exit;
}
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
__END__

E�er yukar�daki numconv program�n� download etmek istiyorsan�z buraya t�klay�n.
Sopnraki paragraflarda bu programa daha yak�ndan bakaca��z ve anlamaya �al��aca��z.

 

If-ifadeleri

If-ifadeleri perl'de 2 �ekilde uygulan�r:
expr if (cond);
veya
if (cond) BLOCK [[elsif (cond) BLOCK ...] else BLOCK]

BLOCK s�sl� parantezler {}i�ine yaz�lan say�sal ifadedir. Bu �rnekteki gibi yazabilece�iniz anlam�na gelir:

printf("hello\n") if ($i);

if ($i == 2){
   printf("i is 2\n");
}elsif ($i == 4){
   printf("i is 4\n");
}else{
   printf("i is neither 2 nor 4\n");
}

T�pk� C'deki gibi k�sa yol operat�leri && ve || kullan�labilir.
printf("hello\n") if ($i);
a�a��daki �ekilde de yaz�labilir;
($i) && printf("hello\n");
�zellikle "||" bizim templatemizde oldu�u gibi konu�ma diline olduk�a iyi �evirir.
getopts("d:x:h")||�l "ERROR\n";
"Opsiyonu al veya �l". Fonksiyon �l() temel olarak ��k�� taraf�ndan takip edilen printf'e denktir. Bir mesaj yazd�r�r ve program� sonland�r�r.
&getopts("d:x:h")||die "ERROR\n";
ifadesi ! i�aretinin operat�r de�il de mant�ksal bir ifade oldu�u a�a��daki ifadeye denktir;
die "ERROR\n"; if (! &getopts("d:x:h"));
Bu tekrar ��yle yaz�labilir;
die "ERROR\n"; unless (&getopts("d:x:h"));
unless if-not'la ayn� anlama gelir ve onu okumak if(!..) 'i okumaktan daha kolayd�r. G�rd���n�z gibi perl'de if-ifadesi yazman�n birden fazla yolu var. Hepsini kullanmak zorunda de�ilsiniz. Sizin i�in en rahat olan�n� kullan�n.

 

De�i�kenler

�lk perl yaz�s�nda g�rd�k ki say�sal de�i�kenler ($-de�i�kenleri) a��klanmadan kullan�ld�. Onlar tam kullan�ld�klar� an var olurlar. Bu k���k programlar i�in ho� bir �zellik ancak daha b�y�k programlarda bulmas� zor hatalar getirebilirler. Bir de�i�keni a��klamak derleyiciye yaz�m hatalar� i�in fazladan kontrol yapma olana�� sa�lar.
"use strict;" forces you to declare everything.
A�a��daki do�ru kod �rne�ini inceleyiniz:

#!/usr/bin/perl
use strict;
my $i=1;
print "i is $i\n";

Bu program do�rudur ve "i is 1"i �retir. �imdi d���nelim ki i yerine yanl��l�kla j yazd�k:

#!/usr/bin/perl
#
$i=1;
print "i is $j\n";

Bu kod perl'de �al���r ve "i is "i �retir. Perl sabit de�eri "use strict;" b�yle bir program i�in derleyiciyi �ikayet etmeye zorlayabilir. "strict"i kulland���n�z zaman her �ey tan�t�lm�� olmal� aksi takdirde bir hata mesaj�yla kar��la��rs�n�z.

#!/usr/bin/perl
use strict;
my $i=1;
print "i is $j\n";

Bu a�a��daki mesaj�n gelmesine neden olur ve yaz�m yanl���n� kolayca g�rmenizi sa�lar.

Global symbol "$j" requires explicit package name at ./vardec line 4.

Execution of ./vardec aborted due to compilation errors.

Exit 255

De�i�kenler perl'de "my" kullanarak tan�t�labilir ya da daha �nceden �at�da g�rd���m�z gibi "use vars qw()" kullanarak da tan�t�labilir:
use vars qw($opt_h);

Geni� �apl� de�i�kenler use varsile tan�t�l�r. Bu de�i�kenler i�erilen t�m k�t�phanelerde de geni� �apl�d�r.
Ge�erli program dosyas�na (bu dosyadaki t�m de�i�mezler aras�nda geni� �apl� olarak) yerle�en de�i�kenler program�n ba��nda (bir de�i�mezin d���nda) myile tan�t�lmal�.
Ge�erli de�i�meze yerle�en de�i�kenler myile de�i�mezin i�inde tan�t�l�r.

Kabuk programlamada deneyimli insanlar bir de�i�keni tan�t�rken veya ona de�er atarken $ i�aretini unutmaya meyillidir. Bu perl'de m�mk�n de�il. Say�sal de�i�ken kullan�rken daima $ i�aretini yaz�n.

Ayr�ca bir de�i�keni tan�t�rken ona direk bir de�er atayabilirsiniz. my $myvar=10; $myvar de�i�kenini tan�t�r ve onun ilk de�erini 10 olarak koyar.

 

De�i�mezler

Biz �nceden "help" de�i�mezini yukar�daki numconv program�nda kullanm��t�k. De�i�mezler sizin kendi fonksiyonlar�n�z�n program�nda kullan�labilir. Program�n�z� yap�land�rman�zda yard�mc� olur.
Bir de�i�mez program metinindeki (�nce ya da sonra �a��r�l�r. �nemli de�il) herhangi bir yerinin i�ine koyulabilir. Bir de�i�meze sub name(){... ile ba�lars�n�z ve $retval=&name(...arguments...) ile �a��r�rs�n�z. D�n�� de�eri de�i�mezde son �al��t�r�lan ifadenin de�eridir. De�i�meze verilen arg�manlar de�i�mezin i�indeki koda �zel bir s�rada @_ ge�er. Bu konuya Perl III'de s�ralardan bahsederken daha detayl� bakaca��z. �imdilik say�sal de�i�kenlerin de�erinin de�i�mez i�inde shiftkullanarak okunabildi�ini bilmek yeterli. Burada bir �rnek:

#!/usr/bin/perl
use strict;
my $result;
my $b;
my $a;
$result=&add_and_duplicate(2,3);
print "2*(2+3) is $result\n";

$b=5;$a=10;
$result=&add_and_duplicate($a,$b);
print "2*($a+$b) is $result\n";

# add two numbers and multiply with 2:
sub add_and_duplicate(){
    my $locala=shift;
    my $localb=shift;
    ($localb+$locala)*2;
}
 

Ger�ek bir program

�imdi bir�ok Perl s�zdiziminde ve dilin elemanlar�nda yol ald�ktan sonra,ger�ek bir program yazman�n tam s�ras�!
Perl az bir programlama �abas� ile metin dosyalar�n� i�lemek i�in dizayn edilmi�tir. �lk Perl program�m�z k�saltmalar�n listesini kar��la�t�rmal�, sonra da bu listedeki kopyalar� bulmal�.Kopyalarla listede baz� zamanlar ortaya ��kan k�saltmalar� kastediyoruz. Liste a�a��daki gibi g�r�n�r:

It is easy to manipulate text files with Perl
AC Access Class
AC Air Conditioning
AFC Automatic Frequency Control
AFS Andrew File System
...

You can download the list here. The syntax of this file is:

B�yle bir metin dosyas�n� nas�l okumal�? A�a��da, metni sat�r sat�r okumak i�in baz� Perl kodlar� verilmi�tir:


....
open(FD,"abb.txt")||die "ERROR: can not read file abb.txt\n";
while(){
   #do something
}
close FD;
....

A��k fonksiyon bir dosya betimleyicisini ilk arguman olarak, dosyan�n ad�n� da ikinci arguman olarak al�r. Dosya betimleyicileri baz� �zel de�i�ken �e�itlerindendir. Siz sadece bunu a��k fonksiyonun i�ine koyun, veriyi dosyadan okuyan fonksiyonda kullan�n ve en sonunda da kapal� fonksiyona verin. Dosya <FD>ile okunur. <FD>. while d�ng�s�ne arguman olarak verilebilir ve bu sonradan sat�r okuyucusuyla bir sat�rda sonlan�r.
Genel olarak dosya betimleyicileri Perl'de �stel ifadeli harfler olarak yaz�l�r.

Peki bu veri nereye gidiyor? Perl'�n birka� �rt�k de�i�kenleri vard�r.Bunlar sizin hi� ifade etmedi�iniz de�i�kenlerdir .Onlar her zaman oradad�rlar. B�yle bir de�i�ken de $_ dir.Bu de�i�ken genellikle �stteki while d�ng�s�nde okunan sat�r� korur.Hadi �imdi deneyelim!( kodu y�kle:

#!/usr/bin/perl
use strict;
my $i=0;
open(FD,"abb.txt")||die "ERROR: can not read file abb.txt\n";
while(<FD>){
   # increment the line counter. You probably
   # know the ++ from C:
   $i++;
   print "Line $i is $_";
}
close FD;
The implicit variable $_ holds the current line.

G�rd���n�z gibi print "Line $i is $_\n"YAZMADIK.$_ de�i�keni ,bulunan sat�r�, yeni sat�r komutu (\n)'i i�eren metin dosyas�ndan korur.

�imdi dosyay� nas�l okumam�z gerekti�ini biliyoruz. Asl�nda program� tamamlamak i�in iki �ey daha ��renmemiz gerekiyor :

  1. K�saltmalar� sat�r�n ba��ndan nas�l okuyaca��m�z
  2. Perl'�n kar���k tablolar�n�n nas�l �al��t���

D�zenli Anlat�m metin katar�nda bir �r�nt� aramak i�in sofistike ortalamalar sa�lar. Biz ilk bo�luktan itibaren bir sat�rdaki ilk katar� ar�yoruz . Ba�ka bir deyi�le g�r�nt�m�z "sat�r�n ba��--birka� karakter ama bo�luk de�il--bir bo�luk"tur. Perl d�zenli anlat�m�nda bu ^\S+\stir. E�er bunu bir m// i�ine koyarsak;Perl bu anlat�m� $_ de�i�kenine atayacakt�r (Hat�rlatma:Bu de�i�ken, bulunan sat�r� da tutuyordu!).\S+ d�zenli anlat�mlarda "bir ka� karaktere ama bo�luk de�il" kar��l�k gelir. E�er \S+'in etraf�na parantez koyarsak, $1 de�i�keninde arkada "bo� karakter de�il"i al�r�z. Bunu kendi program�m�za ekleyebiliriz:

#!/usr/bin/perl -w
# vim: set sw=8 ts=8 si et:
#
use strict;
# global variables:
use vars qw($opt_h);
my $i=0;
use Getopt::Std;
#
&getopts("h")||die "ERROR: No such option. -h for help.n";
&help if ($opt_h);
#
open(FD,"abb.txt")||die "ERROR: can not read file abb.txt\n";
while(<FD>){
    $i++;
    if (m/^(\S+)\s/){
        # $1 holds now the first word (\S+)
        print "$1 is the abbreviation on line $i\n";
    }else{
        print "Line $i does not start with an abbreviation\n";
    }
}
close FD;
#
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
sub help{
     print "help text\n";
     exit;
}
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
__END__

Match operat�r�(m/ /)e�er d�zenli anlat�m ba�ar�l� bir �ekilde, bulunan sat�ra uygulan�rsa 1'e d�ner . Bu y�zden bunu bir if ifadesinin i�inde kullanabiliriz. $1'in ger�ekten ge�erli veriyi i�ermesini sa�lamak i�in $1'i kullanmadan �nce, match operat�r�n�n etraf�nda her zaman bir if ifadesi kullanmal�y�z.

   

Kar���k Tablolar

�imdi dosyay� okuyup ve k�saltmay� alabiliriz ve de b�t�n eksik olan bizim bu k�saltmalar� daha �nceden okuyup okumad���m�z� g�rmek! Burada yeni bir perl veri tipine gereksinimiz var: Kar���k Tablolar. Kar���k tablolar bir katar taraf�ndan indekslenebilen s�ralard�r. B�t�n Kar���k Tabloyu kastetti�inizde, de�i�kenin isminin �n�ne bir % i�areti koyar�z. Ki�isel bir de�er okumak istedi�iniz zaman $variable_name{"index_string"} kullan�rs�n�z. Ayn� $'� di�er de�i�kenler i�in oldu�u gibi sadece normal bir skaler de�i�kenmi� gibi kar���k tablonun i�ine alan olarak kullanabiliriz. ��te bir �rnek:

#!/usr/bin/perl -w
my %htab;
my $index;
# load the hash with data:
$htab{"something"}="value of something";
$htab{"somethingelse"}=42;
# get the data back:
$index="something";
print "%htab at index \"$index\" is $htab{$index}\n";
$index="somethingelse";
print "%htab at index \"$index\" is $htab{$index}\n";

When running this program we get:

%htab at index "something" is value of something
%htab at index "somethingelse" is 42

�imdi program�m�z tamamland�:

 1  #!/usr/bin/perl -w
 2  # vim: set sw=4 ts=4 si et:
 3  # 
 4  use strict;
 5  # global variables:
 6  use vars qw($opt_h);
 7  my %htab;
 8  use Getopt::Std;
 9  #
10  &getopts("h")||die "ERROR: No such option. -h for help.n";
11  &help if ($opt_h);
12  #
13  open(FD,"abb.txt")||die "ERROR: can not read file abb.txt\n"; 
14  print "Abbreviations with several meanings in file abb.txt:\n";
15  while(<FD>){ 
16      if (m/^(\S+)\s/){
17          # we use the first word as index to the hash:
18          if ($htab{$1}){
19              # again this abbrev:
20              if ($htab{$1} eq "_repeated_"){
21                  print; # same as print "$_";
22              }else{
23                  # this is the first duplicate we print first
24                  # occurance of this abbreviation:
25                  print $htab{$1};
26                  # print the abbreviation line that we are currently reading:
27                  print;
28                  # mark as repeated (= appears at least twice)
29                  $htab{$1}="_repeated_";
30              }
31          }else{
32              # the first time we load the whole line:
33              $htab{$1}=$_;
34          }
35      }
36  } 
37  close FD; 
38  #
39  #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
40  sub help{
41          print "finddup -- Find abbreviations with several meanins in the
42  file abb.txt. The lines in this file must have the format:
43  abrev meaning
44  \n";
45          exit;
46  }
47  #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
48  __END__ 

Program� buraya basarak download edebilirsiniz.

Nas�l �al���r? Dosyay� sat�r sat�r okuduk ve sat�rlar� hash'�m�zde yani %htab'da depolad�k (line 33). Hashdaki dizin k�saltmad�r. Hash'� y�klemeden �nce hash'da daha �nceden y�klenmi� bir�ey var m� diye kontrol etmeliyiz(line 18). E�er bir�ey varsa iki ihtimal vard�r:

  1. Bu ilk kopyad�r.
  2. Bu k�saltmada daha �nceden birka� kopya varm��

�ki olay� birbirinden ay�rdedebilmek i�in "_repeated_"katar�n� hash'�n i�ine, bizim dosyan�n i�inde �oktan bir kopya buldu�umuzu belirtmek i�in, yazar�z (line 29).

Bu belki de kodu download edebilmek i�in en iyi yoldur Hadi bir s�nay�n!

 

Bir sonraki ne?

Bu makalede �oktan perl dilinin baz� detaylar�n� ��rendiniz. Hen�z perl'�n sahip oldu�u b�t�n veri tiplerini ��renmediniz ve belki de yukar�daki program�m�zda "abb.txt"dosya ad�n�n zor kodlanmas�n� engellemenin m�mk�n olup olmad���n� merak ediyorsunuz. Siz �oktan bunu engellemek i�in nas�l bir opsiyon kullanman�z gerekti�ini biliyorsunuz(e.g finddup -f abb.txt). Program� de�i�tirmeye �al���n!Komut sat�r�n� ve veri tipi s�ras�n� okuman�n genel yolu bir sonraki makalede verilecektir.


Web sayfalar� LinuxFocus Edit�r tak�m� taraf�ndan devam ettirilmektedir.
(c) Guido Socher
LinuxFocus 1999
en -> tr Gonca Ak� & Hale Asl� �alkaya

1999-11-06, generated by lfparser version 0.9