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: |
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.
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.
Ş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 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.
İ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.
|
#!/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);
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.
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
#!/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; } |
Ş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:
|
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; |
|
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 :
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.
Ş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 |
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:
İ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!
(c) Guido Socher LinuxFocus 1999 |
1999-11-06, generated by lfparser version 0.9