Home Map Index Search News Archives Links About LF
[Top bar]
[Bottom bar]
Bu makalenin farkl� dillerde bulundu�u adresler: English  Castellano  Deutsch  Francais  Nederlands  Turkce  

convert to palmConvert to GutenPalm
or to PalmDoc

[Photo of the Author]
taraf�ndan Guido Socher

Yazar hakk�nda:

Guido eski t�fek bir Linux fanati�i ve Perl k�r�c�s�d�r. Kendi g�rsel y�resini a�a��daki linkte bulabilirsiniz. www.oche.de/~bearix/g/.


��erik:

Perl k�s�m III

�eviri : Selahattin Din�

[Illustration]

�zet:

Perl k�s�m I size Perl hakk�nda genel bir fikir verecektir. Perl'in k�s�m II'sinde ilk yard�mc� program yaz�ld�. K�s�m III'te ise dizilere daha yak�ndan inceleyece�iz.



 

Diziler

Bir dizi, kendisine bir indeks ile ula��labilen de�i�kenlerin bir listesini i�erir. Bilindi�i gibi "normal de�i�kenler", ayn� zamanda y�ns�z(skaler) de�i�kenler olarak bilinir ve isimleri de dolar($) i�aretiyle ba�lar. @-i�aretiyle ba�layan dizilerde de dizi bir �ok y�ns�z de�i�ken i�erir. Bundan dolay� dizi i�inde �zel alanlar belirtti�imizde dolar i�aretini yazmay� unutmamal�y�z. Hep beraber �u �rne�e bir g�z atal�m:

!/usr/bin/perl -w
# vim: set sw=8 ts=8 si et:
# declare a new array variable:
my @myarray;
# initialize it with some data:
@myarray=("data1","data2","data3");
# access the first element (at index 0):
print "the first element of myarray is: $myarray[0]\n";
G�rd���n�z gibi her�eyden bahsetti�imizde @myarray yazd�k ve �zel bir elemntten bahsederken $myarray[0] yazd�k. Perl dizileri index 0 dan ba�larlar. Yeni indexler ise veri i�aretledi�imiz an hemn olu�turulur. Bildirme zaman�nda dizinin b�y�kl���n�n ne kadar oalca��n� bilmek zorunda de�ilsiniz. Yukar�da g�rd���n�z gibi bir veri demetini parantezlerin arkas�na bir noktal�virg�l koyarak bir araya toplayabilirsiniz.
("data1","data2","data3")
ger�ekten anonim bir dizidir. Bundan dolay� bu anonim diziden ikinci eleman� almak i�in ("data1","data2","data3")[1]
yazabilirsiniz:
!/usr/bin/perl -w
print "The second element is:"
print ("data1","data2","data3")[1];
print "\n"
 

Diziler �zerinde d�ng�

Perl'de foreach d�ng�s� dizinin b�t�n elemanlar� �zerinde bir d�ng� kurmay� olanakl� k�lar. Bu a�a��daki gibi �al���r:
#!/usr/bin/perl -w
# vim: set sw=8 ts=8 si et:
my @myarray =("data1","data2","data3");
my $lvar;
my $i=0;
foreach $lvar (@myarray){
   print "element number $i is $lvar\n";
   $i++;
}
Bu program �al��t�r�ld���nda �u sonucu verir:
element number 0 is data1
element number 1 is data2
element number 2 is data3
foreach ifadesi diziden her bir eleman� al�p d�ng� de�i�kenine sokar(yukarda �rnekteki $lvar gibi) �unu �nemle belirtmek gerekir ki de�erler diziden kopyalanmak suretiyle d�ng�n�n i�ine sokulmuyorlar. D�ng� de�i�keni yerine baz� i�aret�i ve d�ng� de�i�kenlerinin de�i�tirilmesi dizinin i�indeki elemanlar� de�i�tirir. A�a��daki program dizinin i�indeki b�t�n elemanlar� b�y�k harf yapar. Perl deki tr/a-z/A-Z/ Unix'teki "tr" komutuna benzer. Bahsedilen ko�ullarda b�t�n harfleri b�y�k harfe �evirir.
#!/usr/bin/perl -w
# vim: set sw=8 ts=8 si et:
my @myarray =("data1","data2","data3");
my $lvar;
print "before:\n";
foreach $lvar (@myarray){
    print "$lvar\n";
    $lvar=~tr/a-z/A-Z/;
}
print "\nafter:\n";
foreach $lvar (@myarray){
    print "$lvar\n";
}
Program� �al��t�rd���n�z zaman g�receksiniz ki sadece @myarray i�eren ikinci d�ng� de�i�kenleri b�y�k harf yapacakt�r:
before:
data1
data2
data3

after:
DATA1
DATA2
DATA3
 

Komut sat�r�

Perl II'de g�r�ld��� �zere bir &getopt fonksiyonu komut sat�r�n� okumada ve komut sat�r�yla ger�ekle�tirilebilen herhangi bir se�ene�i kullanmada kullan�labilir. &getopt fonksiyonu C'dekiyle ayn�d�r. Bu bir kitapl�k fonksiyonudur. Komut sat�r�ndan de�i�ken almak i�in Perl'de kullan�lan dizi @ARGV olarak isimlendirilmi�tir. &getopt fonksiyonu sadece bu @ARGV yi al�r ve elemanlar� de�erlendirir.
C'dekinden farkl� olarak program�n ismi dizideki ilk eleman�n i�eri�i de�il komut sat�r�n�n ilk eleman� program ismidir. E�er perl program�n�n ismini ��renmek istiyorsan�z $0'� okumak zorundas�n�z. Makalemizin konusu bu olmad��� i�in �imdilik buna de�inmeyece�iz. Bu da add adl� �rnek program�m�z. Bu program komut sat�r�ndan iki rakam al�r ve bunlar� toplar:
> add 42 2
42 + 2 is:44
.... ve bu da program�m�z:
#!/usr/bin/perl -w
# check if we have 2 arguments:
die "USAGE: add number1 number2\n" unless ($ARGV[1]);
print "$ARGV[0] + $ARGV[1] is:", $ARGV[0] + $ARGV[1] ,"\n";
 

Bir Y���t

Perl'de bir diziyi y���t olarak kullanan kendinden menkul bir dizi fonksiyon vard�r. Bir sonraki program mevcut bir diziye iki eleman ekler:
#!/usr/bin/perl -w
my @myarray =("data1","data2","data3");
my $lvar;
print "the array:\n";
foreach $lvar (@myarray){
    print "$lvar\n";
}
push(@myarray,"a");
push(@myarray,"b");
print "\nafter adding \"a\" and \"b\":\n";
while (@myarray){
    print pop(@myarray),"\n";
}
Pop, dizinin sonundaki eleman� ��kar�r ve dizi bo�alana kadar while d�ng�s� �al���r.  

Dizin Okuma

Perl'�n bir dizinin i�eri�ini okumak i�in bize sundu�u fonksiyonlar; opendir, readdir fonksiyonlar�d�r. readdir, bir diziye b�t�n dosya isimleriyle d�ner. foreach d�ng�s�n� kullanarak b�t�n dosya isimlerini d�nd�re bilir ve bir isim vererek arama yapabilirsiniz. Bu �rnek program i�inde bulunulan dizinde verilen dosya ismini arar.
#!/usr/bin/perl -w
# vim: set sw=8 ts=8 si et:
die "Usage: search_in_curr_dir filename\n" unless($ARGV[0]);
opendir(DIRHANDLE,".")||die "ERROR: can not read current directory\n";
foreach (readdir(DIRHANDLE)){
    print"\n";
    print "found $_\n" if (/$ARGV[0]/io);
}
closedir DIRHANDLE;
�imdi programa bir bakal�m. �lk �nce kullan�c�n�n komut sat�r� arguman�n� sa�lay�p sa�lamad���n� kontrol ettik. E�er sa�lanmam��sa kullan�m bilgisini ekrana bast�rd�k ve ��kt�k. Sonra i�inde bulundu�umuz dizini a�t�k ("."). opendir fonksiyonu, dosyalar i�in ge�erli olan the open functionsile ayn�d�r. �lk arg�man readdir ve closedir fonksiyonlar�n� ge�mek i�in gerekli olan dosya tan�mlay�c�s�d�r. �kinci arg�man dizine a��lan patikad�r.
Sonraki foreach d�ng�s�ne gelir. �lk ilgi�ekici durum d�ng� de�i�keninin atlanmas�d�r. Perl bu durumda sizin i�in sihirli bir form�l geli�tirir ve $_ ad�nda bir de�i�ken olu�turur. Bu de�i�ken de d�ng� de�i�keni olarak kullan�l�r. readdir(DIRHANDLE) fonksiyonu bir diziye d�ner ve biz de her elemana bakmak i�in foreach d�ng�s� kullan�l�r. /$ARGV[0]/io ise $ARGV[0] i�indeki s�radan ifadeyi $_ de�i�kenine ile e�le�tirilir(kar��la�t�r�l�r). Burdaki io ise aramay� b�y�k k���k harf e�le�tirmesiz yapmas�n� ve s�radan ifadeyi sadece bir kere derlemesini ifade eder. Bir sonraki ise program� daha h�zl� hale getiren bir iyile�tirmedir. S�radan ifadenin i�inde bir de�i�keniniz oldu�u zaman bunu kullanabilirsiniz ve emin olabilirsiniz ki de�i�ken �al��t�rma an�nda de�i�mez.
�imdi bir deneyelim. Varsayal�m ki i�inde bulundu�umuz dizinde article.html, array1.txt ve array2.txt ad�nda dosyalar olsun. Sonra "HTML" ile aratt���m�zda �u sonu� verilecektir.
>search_in_curr_dir HTML
.
..
article.html
found article.html
array1.txt
array2.txt
G�rd���n�z gibi readdir fonksiyonu 2 tane fazladan dosya buldu. "." ve "..". Bunlar i�inde bulunulan ve bir �nceki dizinlerin isimleri.  

Bir dosya bulucusu

Bu makaleyi biraz karma��k ve daha kullan��l� bir �rnekle bitirmek istiyorum. Bu bir dosya bulma program� olacak. Program�m�z�n ad�n� pff((perl file finder) perl dosya bulucusu) koyal�m. Bu temel olarak yukardaki program gibi �al��acak fakat farkl� olarak al dizinlerde de arama yapabilecek. Peki b�yle bir program� nas�l yapaca��z? Yukarda i�inde bulunulan dizinde arama yapan baz� kodalar�m�z vard�. ��inde bulundu�umuz dizinden ba�lamam�z gerekir fakat (. ve .. d���nda) e�er i�inde bulundu�umuz dizinin i�inde ba�ka dizinler de varsa bunlar�n i�inde de arama yapmak gerekir. Bu tipik bir yinelemeli algoritmad�r.
sub search_file_in_dir(){
  my $dir=shift;
  ...read the directory $dir ....
  ...if a file is again a directory
    then call &search_file_in_dir(that file)....
}
if (-d "$file" && ! -l "$dir/$_"){....} yap�s�n� kullanarak bir dosyan�n dizin mi yoksa bir symlink mi oldu�unu anlayabilirsiniz.
�imdi program� yazabilmek i�in gereken b�t�n codlar�m�z� alal�m. the actual code (pff.gz).
#!/usr/bin/perl -w
# vim: set sw=8 ts=8 si et:
# written by: guido socher, copyright: GPL
#
&help unless($ARGV[0]);
&help if ($ARGV[0] eq "-h");

# start in current directory:
search_file_in_dir(".");
#-----------------------
sub help{
    print "pff -- perl regexp file finder
USAGE: pff [-h] regexp

pff searches the current directory and all sub-directories
for files that match a given regular expression.
The search is always case insensitive.

EXAMPLE:
search a file that contains the string foo:
    pff foo
search a file that ends in .html:
    pff \'\\.html\'
search a file that starts with the letter \"a\":
    pff \'^a\'
search a file with the name article<something>html:
    pff \'article.*html\'
    note the .* instead of just *
\n";
    exit(0);
}
#-----------------------
sub search_file_in_dir(){
    my $dir=shift;
    my @flist;
    if (opendir(DIRH,"$dir")){
        @flist=readdir(DIRH);
        closedir DIRH;
        foreach (@flist){
            # ignore . and .. :
            next if ($_ eq "." || $_ eq "..");
            if (/$ARGV[0]/io){
                print "$dir/$_\n";
            }
            search_file_in_dir("$dir/$_") if (-d "$dir/$_" && ! -l "$dir/$_");
        }
    }else{
        print "ERROR: can not read directory $dir\n";
    }
}
#-----------------------
�imdi birazc�k program� inceleyelim. �lk �nce kullan�c�n�n komut sat�r�na ge�erli komutu girip girmedi�ini test ettik. E�er de�ilse bir hata mesaj� ��kart�p k���k bir yard�m yaz�s� ��karaca��z. Ayr�ca -h se�ene�i verilirse ayr� bir yard�m metni g�sterece�iz. Aksi durumda i�inde bulundu�umuz dizinden itibaren aramaya ba�lar�z. Yukarda tan�mlanan yinelemeli(recursive) algoritmay� kullan�r�z. Dizini oku, dosyalar� ara, dosyan�n bir dizin olup olmad���n� test et, e�er olumlu ise(dizin ise) search_file_in_dir() fonkisoyunu tekrar �a��r.

�fadenin i�inde, dizinleri kontrol etti�imiz yerde ayn� zamanda dizinin ba�ka bir dizine link olmad���n� da kontrol etmi� oluruz. Bunu kontrol etmemiz gerekir ��nk� belki birisi ".." dizinine sym-l�nk olu�turmu�tur. B�yle bir kontrol yap�lmad��� takdirde program sonsuz d�ng�ye girecektir.

next if ($_ eq "." || $_ eq ".."); ise hen�z �zerinde konu�mad���m�z bir ifadedir. "eq" operator ise Perl'deki katar kar��la�t�rma operat�r�d�r. Burda ise $_ de�i�keninin i�eri�ini ".." veya "." e�it olup olmad���n� anlamak i�in test ettik. E�er bu e�itse "next" ifadesi �al��t�r�ld�. Bir foreach d�ng�s� i�indeki "next" ifadesi d�ng�n�n en ba��na d�n�l�p dizinin ikinci eleman� ile d�ng�ye devam edilmesi anlam�na gelir. Bu C'deki "continue" durumuna benzer.  

Kaynaklar

A�a��da Perl hakk�nda yaz�lm�� baz� ilgin� yaz�lar�n bir listesini veriyoruz.  

Bu yaz� i�in g�r�� bildiriminde bulunabilirsiniz

Her yaz� kendi g�r�� bildirim sayfas�na sahiptir. Bu sayfaya yorumlar�n�z� yazabilir ve di�er okuyucular�n yorumlar�na bakabilirsiniz.
 talkback page 

G�rsely�re sayfalar�n�n bak�m�, LinuxFocus Edit�rleri taraf�ndan yap�lmaktad�r
© Guido Socher, FDL
LinuxFocus.org

Buray� klikleyerek hatalar� rapor edebilir ya da yorumlar�n�z� LinuxFocus'a g�nderebilirsiniz
�eviri bilgisi:
en -> -- Guido Socher
en -> tr Selahattin Din�

2001-03-09, generated by lfparser version 2.9