TRForumcu.NeTWebmaster / Web Dizayn Scriptler / Programlama DilleriWeb tasarım / ASp, PHP,CGI Scriptler (Moderatör: Gondolin)Cgi - Perl Kullanımı
Konu Bilgileri
Konu Başlığı Cgi - Perl Kullanımı
Cevaplar 10
Sonraki Sonraki Konu
Görüntüleyenler0 Üye ve 1 Ziyaretçi konuyu incelemekte.
Görüntülenme 434
Önceki Önceki Konu
Sayfa: 1 [2]   Aşağı git
Yazdır
Konu Derecelendirme: 0 Bookmark and Share
Konu: Cgi - Perl Kullanımı  (Okunma Sayısı 434 defa) EkleBunu Sosyal Paylaşım Butonu
Gondolin
Bölüm Sorumlusu
*


Mesaj : 1.169
Forum Para : 7896.00 YTL
« Yanıtla #6 : 02 Mayıs 2008, 11:06:01 »


Karşılaştırma Operatörleri
Karşılaştırma   Matematik İşlemleri   String İşlemleri
Eşittir   ==   eq
Eşit değildir   !=   ne
Küçüktür   <   lt
Büyüktür   >   gt
Küçük veya eşittir   <=   le
Büyük veya eşittir   >=   ge
/////////////////////////////////////////KUTU BİTTİ//////////////////////
Bir karşılaştırmada, ileri sürdüğümüz iki koşul da doğru değilse, bir üçüncü, dördüncü.. n’nci koşulu arayabiliriz. Bunu “elseif” deyimi ile yaparız. Şu senaryoyu zihninizde canlandırın:
if(şart1) { işlem1 }
   elseif(şart2) { işlem2 }
   elseif(şart3) { işlem3 }
   elseif(şart4) { işlem4 }
   else(şart5) { işlem5 }
Bu, Perl açısından sırasıyla şu sınamaların yapılması demek:
1. Şart 1 doğru ise işlem 1’i yap; değilse bir sonraki satıra bak; ne komut görürsen onu icra et!
2. Şart 2 doğru ise işlem 2’yi yap; değilse bir sonraki satıra bak; ne komut görürsen onu icra et!
3. Şart 3 doğru ise işlem 3’i yap; değilse bir sonraki satıra bak; ne komut görürsen onu icra et!
4. Şart 4 doğru ise işlem 4’i yap; değilse bir sonraki satıra bak; ne komut görürsen onu icra et!
5. Şart 5 doğru ise işlem 5’i yap; değilse bir sonraki satıra bak; ne komut görürsen onu icra et!
elseif deyimini kullandıysak, else‘e gerek kalmaz; ama programcılık geleneğine göre, else daima kullanılır.
eğer...değilse şeklindeki mantık testlerinin bir diğer türü “değilse” sınavı olabilir. Yani “Sayı2 5’e eşit değilse şunu yap!” gibi. Bunu unless karşılaştırma deyimi ile yazarız:
unless ($ad eq ‘Mustafa7) {
   print “Senin adın Mustafa değil!” }
unless deyimi yerine if deyimini not karşılaştırma operatörüyle birlikte kullanabiliriz:
if(not($ad eq ‘Mustafa’)) {
   print “Senin adın Mustafa değil!” }
Şimdi programımıza dönelim ve bu öğrendiklerimizin nasıl uygulandığını görelim. Programda çevre değişkenlerini tutan %ENV İlişkili Dizi değişkeni içindeki REQUEST_METHOD anahtarının değerinin GET’e eşit olup olmadığını sınıyoruz. if deyimi ile yaptığımız sınamanın sonucu doğru ise (yani REQUEST_METHOD anahtarının değerinin GET’e eşit ise) ilk komut-deyim bloku icra edilecektir. Bu blokta yapılacak iş, çevre değişkenlerinden QUERY_STRING’in içindeki String’i split fonksyonu ile “&” işaretlerinden bölümlere ayırmaktır. Bu işlem sonucu ortaya çıkan bağımsız String’leri @girdi dizi değişteninde (Array) toplayacağız.
Fakat ya yaptığımız sınama doğru değilse, yani REQUEST_METHOD anahtarının değeri GET’e eşit değilse? Bu durumda iki şey olabilir: ya bu değer POST’a eşittir; ya da değildir. Peki, önce bu değerin POST’a eşit olup olmadığını sınayalım. Bunu elseif ile yapabiliriz. Bu sınamanın sonucu doğru, yani REQUEST_METHOD anahtarının değeri POST’a eşitse, bu kez STDIN’in içeriği ile ilgileneceğiz (ki bunu nasıl yaptığımızı biraz sonra ele alacağız). Peki, REQUEST_METHOD anahtarının değeri POST’a da eşit değilse? Bir Form’un METHOD özelliği ya POST, ya da GET olur. Eğer ikisi de değişse, o zaman Form’da hata var demektir. Bunu sonuncu else deyimine bırakıyoruz; Browser’a hata mesajı yolluyoruz.
Formu biz tasarladığımıza ve Form verilerini hangi yöntemle gönderdiğimizi bildiğimize göre Perl programımızın başında neden böyle bir sorguya ihtiyaç var? Aslında yok! Fakat iyi bir programcı geleneği, hiç bir şeyi şansa bırakmamaktır; belki bizden sonra iş ortaklarınızdan veya çalışma arkadaşlarınızdan biri, veya kız kardeşiniz sizin verdiğiniz gönderme yöntemini beğenmemiş ve Form’da değişiklik yapmış olabilir! Yukarıdaki HTML kodunu değiştirmemek şartıyla, Perl programının bu bölümünü şöyle yazabilirdik:
read (STDIN, $depo, $ENV{'CONTENT_LENGTH'});
@girdi = split(/&/, $depo);

Oku bakiim!
Tabiî buradaki “read()” fonksiyonu dikkatinizi çekmiş olmalı. Neyi okuttuğumuzu ve nasıl okuttuğumuzu ele almadan önce bildiklerimizi bir tazeliyelim: CGI ile bulunduğu Web Server ve ona evsahipliği yapan işletim sisteminin ilişkilerini gözden geçirirken HTTP Server’ın CGI’a iki türlü bilgi aktardığından söz etmiştik. HTTP Server, Internet’ten GET yoluyla bilgi alıyorsa, bu bilgileri çevre değişkenlerinden QUERY_STRING’e depoluyor; POST ile alırsa, standard girdi yöntemini kullanarak, STDIN’in içine koyuyordu. Bu arada STDIN’in yeni boyutu da çevre değişkenlerinden CONTENT_LENGTH’in içine yazılıyordu.
Şimdi, QUERY_STRING ile sizin oluşturduğunuz bir değişkenin hiç farkı yoktur; fakat standard girdi denilen “bilgi tutma alanı” farklıdır. Teknik ayrıntılarına girmeden belirtebileceğimiz başlıca fark, STDIN’in içeriği değişken gibi işlenmez; dolayısıyla önce STDIN’in içeriğini bir değişkene aktarmakta yarar var. STDIN, tıpkı bir dosya gibi okunabilir; dolayısıyla içindeki bilgileri aslında daha sonra sabit diskten dosya okumakta kullanacağımız READ fonksiyonuyla okuyabiliriz. Bu fonksiyonun dört argümanı bulunabilir:
1. Okunacak dosya için oluşturacağımız tutamak (Handle)
2. Okunacak şeyin içine konacağı değişken
3. Okunacak şeyin uzunluğu
4. Okunacak şeyin başladığı konum, pozisyon
Derler ki, Perl’de iki şey vardır: Tekil/Scalar değişken ve dosya tutamağı! Diğer herşey bu iki ögeden türer! Dosya açma, okuma yazma bahsine ve dolayısıyla tutamağın önemine daha sonra döneceğiz; şimdilik sadece şunu bilmek yeterlidir: Perl’ün açacağı dosya için dosya adından başka değişken adına ihtiyacı vardır ve buna tutamak (Handle) denir. Bunu, Perl’ün bir dosyaya kendi içinde verdiği özel bir isim olarak bakabilirsiniz. Standard girdiler ise Perl (diğer bütün Unix programlama dilleri) için açılmış dosya demektir; açılmış ve bir tutamak verilmiş özel bir dosya türü. Tutamağın adı STDIN’dir ve bizim sabit diskte bulunan ve okumak-yazmak için açacağımız bir düz yazı dosyası gibi işlem görür. Bu özel “dosya” içindekileri de okurken, bir değişkenin içine okumak gerekir; read fonksiyonunun ikinci argümanı bunu sağlar. Perl’e okuyacağı şeyin boyutunu, uzunluğgunu söylemeniz gerekir; bu üçüncü argüman olarak yazılır. Dördüncü ve verilmesi zorunlu olmayan argüman ise okumaya başlanacak byte’dır. read fonksiyonu sabit diskteki binary dosyaları okumakta kullanıldığı ve bu dosyaların içeriği sabit diskte byte ölçüsüyle yazıldığı için, konumu byte olarak belirtiriz. Dosyalarımızı genellikle baştan okuttuğumuz için bu argüman genellikle 0 olur.
read fonksiyonunun işleyebilmesi için okuduğu şeyi içine yazacağı bir tekil/Scalar değişken göstermemiz gerekir. Neden tekil/Scalar değişken de dizi değil? Çünkü STDIN’in içindeki herşey, Form’dan gelen bir String’dir. Browser’ın Form verilerini yumak yapıp gönderdiğini hatırlıyor musunuz? Burada “$depo” adını verdiği değıişken, okunan STDIN değerlerini tutacaktır.
Dosya okuma konusunda daha öğrenebileceğimiz çok şey var; STDIN’i okumak için bu kadar bilgi yeter; fakat şunu belirtmek gerekir: Okumaya çalıştığımız dosyanın boyutunu tam olarak belirtmezsek, Perl bilgileri eksik alabilir veya dosyanın bittiği yeri geçer ve dosyaya ait olmayan şeyleri de okuyabilir. Dolayısıyla STDIN’in içerdiği herşeyi okutabilmek için okutacağımız şeyin uzunluğunu çevre değişkenlerinden CONTENT_LENGTH’den öğreniyoruz. Çevre değişkenleri Perl tarafından %ENV adlı özel bir İlişkili Dizi’nin içinde tutulur ve bu dizideki CONTENT_LENGTH anahtarının değerini “$ENV{'CONTENT_LENGTH'}” deyimi ile öğrenebiliriz.
Peki, “read (STDIN, $depo, $ENV{'CONTENT_LENGTH'});” deyimini irdelediğimize göre, şimdi programımızın diğer bölümlerine bakabiliriz. Kodumuzun iş yapan bölümündeki diğer deyim şöyle:
@girdiler = split(/&/, $depo);
split işlevini tanıyoruz: bir değişkenin içeriğini alıyor ve verdiğimiz bölme noktası karakterinden bölümlere ayırıyor. Burada “$depo” değişkenin içerdiği String’i (ve anlamına gelen) ampersand (&) işaretinden böldürüyoruz; elde edilecek bağımsız String’leri “@girdiler” dizi-değişkenine (Array) yazdırıyoruz. Browser’ın Form verisini nasıl yumak yaptığını hatırlıyor musunuz? (İpucu: “isim=Mustafa+Durcan&yas=23”) Browser, Form’daki her bir alanın adı eşittir (=) işaretiyle Form’u tasarlayan veya dolduran kişinin verdiği değerle birleştirip, sonra bunları ampersand (&) işaretiyle birbirine bağlıyordu. Hatırlarsanız, bu arada boşlukların yerine artı (+) işareti konuyor; ayrıca özel karakterlerin yerine de Heksadesimal değerleri yazılıyordu.
$depo değişkeni içindeki String, & işaretinden bölümlere ayrılırsa, elimizde ne kalır? Şunun gibi bir şey:
@girdiler[0]...adi=Mustafa+Durcan
@girdiler[1]...Adres=Web+Teknikleri%2C+Istanbul
@girdiler[2]...Gonder=G%F6nder
@girdiler[3]...Kod=34000
@girdiler[4]...Merak=Siir
@girdiler[5]...eposta= Linklerin Görülmesine İzin Verilmiyor
Linki Görebilmek İçin Üye Ol veya Giriş Yap
@girdiler[6]...mesaj=Mutluluklar+dileriz
@girdiler[7]...yuksek=ON
Burada boşlukların yerine artı (+) işareti konduğuna ve mesela virgül’ün yerine heksadesimal değeri olan “%2C”, ö harfi yerine “%F6” yazıldığına dikkat edin.
Döngüler
Kodumuzu irdelemeye devam edersek, karşımıza çıkan deyimin bir döngü ifadesi olduğunu görüyoruz. Döngü (loop) programcılığın varolma sebebidir! Herhangi bir programın bir kerede yaptığı işi nasıl olsa herkes elle kendisi yapabilir. Fakat aynı iş defalarca tekrar edecekse, bilgisayara ve bilgisayarın bi işi yapmasını sağlayacak olan programa ihtiyaç var demektir. Perl’e bir işi sonuçlanıncaya kadar yaptıran, yani başa dönerek, aynı işi yeniden yapmasını sağlayan bir kaç döngü deyimi vardır. Bunlar while, next..last, for ve foreach deyimleridir.
Bir programın icrası sırasında değişkenlerin değeri değişebilir. (Boşuna ‘değişken’ demiyoruz, değil mi?) while karşılaştırma deyimi, tıpkı yukarıda ele aldığımız if gibi bir değişkenin değerinin belirli bir değere eşit kalması halinde doğrudur; ve sınama sonucu doğru ise sonraki, değilse while blokunu izleyen ilk deyim icra edilir. Bir örnek verelim:
$sayac = 0;
while($sayac < 10) {
   print “Sayaç değişkenin değeri: $sayac\n”;
      $sayac += 1;
}
print “sayaç değişkeni $sayac oldu!”;
Burada Perl, $sayac’ın değeri 10’un altında olduğu sürece ekrana “sayaç değişkeninin değeri:” kelimelerini ve değişkenin o andaki değerini yazdıracak ve değişkenin değerini 1 arttıracaktır. (Aritmetik işlemlere sonra daha yakından bakacağız!) while blokunun sonu olan süslü paranteze ulaştığında Perl, bu blokun başına dönecek ve verdiğimiz koşulu yeniden sınayacaktır. $sayac değişkeni eğer halâ 10’un altında ise, Perl while deyimini yeniden icra edecek yani ekrana “sayaç değişkeninin değeri:” kelimelerini ve değişkenin o andaki değerini yeniden yazdıracak ve değişkenin değerini 1 arttıracaktır. Ta ki, sınama sonucu $sayac değişkeninin değerinin 10 olduğunu gösterinceye kadar. Perl bunu belirlediği anda while blokunun dışına çıkacak ve son deyimi icra edecektir.
Bu arada, while() fonksiyonu ile döngünün yazılışına dikkat edin: döngü bloku, yani while() için ileri sürdüğünüz koşulu içeren parantez kapandıktan sonraki bölüm, süslü parantez içinde ve bu bloku kapatan süslü parantezden sonra noktalı virgül yok.
while blokunda sonsuz-döngü denen hataya düşmek çok kolaydır. Perl, bir türlü gerçekleşmeyen while koşulu ile karşılaştığı zaman sonsuza kadar bu blokun içinde kalır. Bu durumda ne olur? Yukarıdaki kodda şu değişikliği yapın ve sonucu görün:
      $sayac = 0;
Dikkat! Bu sonsuz-döngüden çıkmanın tek yolu, Browser’ı kapatmaktır!
while ne kadar kullanışlı olursa olsun, bir programda karşılaşabileceğimiz her türlü koşulu sınamaya yetmez. onun eksik bıraktığı durumları, for ve foreach ile karşılayabiliriz.
for deyimi sınadığınız koşul gerçekleşinceye kadar devam eder. Yukardaki sayaç örneğini for için yazalım:
for ($sayac = 0 ; $sayac < 10 $sayac += 1) {
   print “Sayaç değişkeni: $sayac”;
}
print “Sayaç değişkeni: $sayac oldu!”;
Bu kodun yaptığı işlem yukarıdaki while ile aynı olduğu için for deyiminin ne kadar kullanışlı olduğu görülemeyebilir. Fakat aşağıdaki kodu Not Defteri ile yazar ve mesela hex.pl adıyla kaydederek, çalıştırırsanız; 255’e kadar ondalık sayıları 16 tabanlı sayı sistemine (Heksadesimal) çevirebilirsiniz. (Şimdilik ele almadığımız fonksiyonlara ve deyimlere aldırmayın!)
#!/usr/local/bin/perl
#hex.pl
print "HTTP/1.0 200 OK\n";
print "Content-Type: text/html\n\n";
print "<HTML>\n";
print "<HEAD>\n";
print "<TITLE>HEX</TITLE>\n";
print "<meta http-equiv=\"content-type\" ***********\"text/html; charset=ISO-8859-9\">\n";
print "<meta http-equiv=\"Content-Type\" ***********\"text/html; charset=windows-1254\">\n";
print "</HEAD>\n";
print "<BODY>\n";
print "<H4>Desimal - Heksadesimal Çevirmeni</H4>\n";
@Heksadesimal = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
for($i = 0; $i <= 255; $i++) {
print sprintf("%3s", $i), "=", $Heksadesimal[int($i / 16)], $Heksadesimal[$i % 16], " ";
   if(($i % Cool == 7) {
   print "\n"
   }
print "<br>\n";
}
print "</BODY>\n";
print "</HEAD>\n";
print "</HTML>\n";

/////////////////////////KUTU///////////////////////
Tek Tırnak.. Çift Tırnak..
Perl’de tek tırnak-çift tırnak farkına daha önce değindik ve tek tırnak içine aldığınız String’in içinde sadece ekranda görüntülenebilen karakterler yer aldığını belirttik. String’lerimiz görüntülenemeyen karakter değerlerini içeriyorsa, bu dizeyi mutlaka çift tırnak içine almamız gerektiğini belirttik. Tek tırnak-çift tırnak farkının bir diğer sonucunun ise String’in içine değişken koyduğumuz zaman ortaya çıktığını söyledik. Şu örneğe bakın:
$ad = ‘Mustafa’
print ‘Senin adın $ad.’
Bu durumda ekranda şu sonucu elde ederiz:
Senin adın $ad.
Perl’ün verdiğimiz String içinde yer alan değişkenin değerini bularak, değişken adı yerine değerini koymasını istiyorsak, print() fonksiyonunu çift tırnakla yazmamız gerekir:
$ad = ‘Mustafa’
print “Senin adın $ad.”
Bu durumda şu sonucu elde ederiz:
Senin adın Mustafa.
/////////////////////KUTU BİTTİ////////////////////////////////
Bu örneklerde de gördüğümüz gibi, for deyiminin üç bölümü vardır; sınanmasını istediğimiz değişkenin başlangıçtaki durumu ($sayac = 0), sonra aranacak koşul ($sayac < 10) ve bu koşul gerçekleşinceye kadar her adımda değişkende olacak değişiklik ($sayac += 1), ve her adımda icra edilecek komutlar ve deyimler. for deyimi sınanan koşul gerçekleşinceye kadar kendi bloku içinde devam eder; koşul yerine gelir gelmez, bloku izleyen ilk deyime geçer.
Kimi zaman sınamayı bir değişkenin bir listeden alacağı bütün değerler için tek tek yapmak isteriz. Burada kilit kavram işlemin tek tek bütün değerler için yapılacak olmasıdır. Ki, bu deyimle, yola çıktığımız form_analiz.pl programındaki foreach deyimine dönmüş oluyoruz!
Form ile aldığımız ve “@girdiler” dizi-değişkenine, tabir yerinde ise, üstüste yığdımız değerleri şimdi tek tek ele alıp, bir işlemden geçirip, daha düzenli şekilde kullanılabilir değişken/değer çiftleri haline getirebiliris. Bu anlamda foreach deyimi mantıksal bir sınamadan çok bir listedeki bütün değerler için ayrı bir işlem yapılması sayılabilir. form_analiz.pl programının ilk foreach deyimini hatırlayalım:
foreach $girdi (@girdiler) {
   ($anahtar, $deger) = split (/=/, $girdi);
Program bu deyimlerde, “@girdiler” dizisinin her bir elemanını tek tek ele alıp, bunu içindeki eşittir (=) işaretinden ikiye bölüp, birinci bölümünü “$anahtar”, ikinci bölümünü ise “$deger” değişkenine yazacaktır.
Bu aşamada, “@girdiler” dizisinin içindeki her bir elemanını alıyoruz, bunu $girdi değişkenine atıyoruz. @girdiler’in sözgelimi birinci elemanını hatırlarsak, döngünün lik adımında $girdi değişkeninin değeri bu String oluşturacak; yani, $girdi’nin değeri “adi=Mustafa+Durcan” olacaktır. Ve split fonksiyonu bu String’i eşittir işaretinden ikiye bölerek, “adi” kelimesini $anahtar değişkenine, “Mustafa+Durcan” kelimelerini $deger değişkenine atayacaktır. (İkinci adımda bu kez “Adres” kelimesi $anahtar değişkenine, “Web+Teknikleri%2C+Istanbul” String’i ise $deger değişkenine atanacaktır.)
Programımızın daha sonraki bölümlerinde bu iki değişkenin içinde bazı metin düzenleme işlemleri yaptıran (eşittir ve tilde işaretleri “=~” bulunan satırlar) deyimler var, ki onlara daha sonra döneceğiz.
////////////////////KUTU/////////////////////

Logged
 
TRForumcu.NeT | Bilgi ve Paylaşım Platformu
Gondolin
Bölüm Sorumlusu
*


Mesaj : 1.169
Forum Para : 7896.00 YTL
« Yanıtla #7 : 02 Mayıs 2008, 11:06:30 »

Metinleri birbirine Nokta ile ekleyebiliriz
Perl’ün metin düzenleme fonksiyonlarına ayrıntılı olarak bakacağız; burada sadece “.=” işlemi üzerinde kısaca duralım.
Sayıları toplarız; String’leri ekleriz. Perl, mükemmel bir rapor yazma dili olarak icad edildiği için olacak, bir çok metin düzenleme aracına ek olarak, özel bir metin ekleme operatörüne sahiptir: Nokta. Bunu bir örnekle anlatmak daha kolay:
$metin1 = ‘kara’;
$metin2 = ‘deniz’;
print $metin1 . $metin2;
bize, tahmin ettiğiniz gibi şunu verir:
karadeniz
Belki ekrana doğrudan “karadeniz” yazdırmanın daha kolay yolları bulunabilir; ama nokta ile metin ekleme işlevinden özellikle mevcut bir değişkenin sonuna yeni ek yaptırmakta yararlanabiliriz.
Diyelim ki, şöyle bir liste yapıyoruz:
$arkadaslar = “Mustafa, Osman, Vildan, Kudret”
Fakat programın daha ileri bir aşamasında $yeni_arkadaslar değişkenine yeni isimler eklediniz. Şimdi bu iki listeyi birleştirmeniz gerekiyor. Değişkenin tümünü yazmak yerine, Perl’e, “Bu değişkeni al, içindekileri şu değişkenin içindeki String’in sonuna ekle!” demek daha kolay olabilir:
$arkadaslar = $arkadaslar . $yeni_arkadaslar;
Eğer bu da size çok zahmetli görünüyorsa, Perl’ün şu kolaylığından yararlanabilirsiniz:
$arkadaslar .= $yeni_arkadaslar;
/////////////////////////////KUTU BİTTİ////////////
$anahtar ve $deger değişkenlerimizin içinde döngünün her adımında sadece birer String var ve ikinci adıma geçmeden önce bu String’leri temelli bir yere yazmak zorundayız; ki ikinci adımda @girdiler’in bir sonraki değerini alalım. İki String’i yanyana alabiler ve birincisini ikincisinin endeksi (Perl diliyle anahtarı), ikincisini de birincisinin değeri yapabileceğimiz değişken türü İlişkili Dizi (Hash, associative Array) listesidir. Şimdi eğer foreach döngüsünün birinci adımında elimizdeki iki değişkeni bir İlişkili Dizi’ye atarsak, döngünün ikinci adımında $anahtar ve $değer değişkenlerine @girdiler’den yeni Stringler alabiliriz. İlişkili Dizi oluşturmanın çeşitli yollarını ele almıştık; bunlardan biri şuydu:
$iliski_dizi_degisken_ismi{$anahtar_ismi_olacak_deger} = $deger_olacak_deger
Bunu bir örnekle yazalım:
$formveri{$anahtar} = $deger;
Buradaki süslü parantezi görünce Perl, bir İlişkili Dizi oluşturmak istediğimizi ve onun bir anahtarı olarak $anahtar adlı değişkenin değerini, bu anahtarın karşıtı olan değer olarak da $deger değişkenin değerini atamak istediğimizi anlar; “%formveri” adındaki İlişkili Dizi değişkeni oluşturur, birinci kaydın anahtarı olarak $anahtar değişkeninin o sıradaki değerini, değeri olarak da $deger değişkeninin o andaki değerini atar. foreach döngüsünün birinci adımında $anahtar’ın değeri “adi”, $deger’in değeri ise içinden artı işaretini atıp yerine boşluk koyduğumuz “Mustafa Durcan” idi. İkinci adımda, %formveri’nin ikinci kaydının anahtarı “Adres”, değeri ise “Web Teknikleri..” olacak ve bu foreach’in sonuna kadar devam edecek. foreach ise @girdiler’in son elemanının işlenmesi ile sona erecek.
Dikkat etmiş olacağınız gibi %formveri’nin kayıtlarını da if ile bir mantık süzgecinden geçiriyoruz. Form’larımızda, bazen aynı alan adına sahip olabilen INPUT etiketleri bulanabilir. Bu etiketler dolayısıyla Form’dan CGI’ya gelen veri yumağında daha sonra İlişkili Dizi’me anahtar olarak yazılmak üzere aynı kelimeden birden fazla bulunabilir. Bunu kabul edemeyiz, çünkü İlişkili Dizi’lerde anahtarların özgün, yani bir adet olması gerekir. foreach döngüsünün sonundaki bu if deyimi, o anda elimizdeki anahtarın daha önce diziye yazılıp yazılmadığını sınamaktadır. %formveri’de bu adla daha önce yazılmış anahtar varsa, o anda $değer’in tuttuğu String, daha önce yazılmış anahtarın kartışı olan değerin sonuna, virgül ile eklenecektir ($formveri{$anahtar} .= ", $deger"Wink; eğer henüz bu anahtar diziye yazılmamışsa, kendisi özgün bir kaydın anahtarı, o andaki $deger de değeri olacaktır ($formveri{$anahtar} = $deger;).
form_analiz.pl’in geri kalan bölümü, %formveri dizisinin anahtar/değer çiftlerini ekrana yazdırmaktan ibaret.
Buraya kadar aslında büyük iş başardık diyebiliriz. Bir çok kişinin belki de CGI ve Perl ihtiyacının başlıca kaynağı olan Form bilgisini alıp, işlemeyi ve bunu ekrana dökmeyi başardık:
<cgi-perl012.tif>
Şimdi ekrandaki bu döküm işleminin biraz daha düzenli olmasını sağlayalım ve bu veriyi ekrana değil de HTTP Server’ın bulunduğu bilgisayarda sabit diske yazdıralım.
Metin, Sayı ve Dosya İşlemleri
Şimdi artık Perl bildiğinize göre.. Evet, evet; hiç merak etmeyin; buraya kadar örnekleri birlikte yaptık ve ele aldığımız fonksiyonları ve deyimleri kullanabilir hale geldi isek, Perl biliyoruz demektir.
Şimdi bu kadar Perl ile neler yapabileceğimize gelelim.
Perl ile matematik işlemleri yapabiliriz; metin oluşturur, sabit diskteki metin dosyalarından veya Internet’ten metin alabiliriz, bu metinleri yeniden biçimlendirebiliriz, ve aldığımız ya da oluşturduğumuz metinleri ya Internet’te birilerine göndeririz, ya da daha sonra gönderilmek üzere sabit diske yazabiliriz. Bu cümleye bakarsanız, Perl ile neredeyse dünyayı yönetebiliriz! (Düşünürseniz, dünyayı yönetmek de sadece buradaki işlemleri yapmaktan ibaret!)
Burada ifade ettiğimiz işlevlerin, dosya işlemleri hariç, hemen hepsini önceki bölümde gördük ve hatta kullandık. Bu bölümde bu işlerin biraz teorisine ve bol bol örneğine bakacağız ve dosya işlemleri ile ilgisini göreceğiz. İnternet sitenizi ziyaret edenlerin dolduracağı Form’ların bir yerlere kaydedilmesini isteriz sonuç itibariyle, değil mi?
Önce biraz Perl reklamı!
Perl, adından da anlaşılacağı gibi bir rapor yazma dilidir. Yani Perl ile yazacağınız programlar, bir yerden bilgi çeker ve bilgiyi rapor haline getirirler. Dolayısıyla Perl’ün çok güçlü metin ve sayı düzenleme araçları vardır. Bu araçlara değinmeden önce, benim daima “Hangisi hangisiydi?” diye karıştırdığım tek tırnak-çift tırnak meselesini yeniden hatırlayalım. Bu karışıklığın kaynak noktası, görünürde iki tür tırnak işaretinin de aynı işlevi yapıyor olmasıdır. Örnek:
$Metin1 = “Merhaba Dünya!”;
$Metin2 = ‘Sana da merhaba, ey ademoğlu!’;
print $Metin1;
print $Metin2;
Bu programı çalıştırın ve ekranda okuduğunuz yazılara lütfen dikkat edin; sonra $Metin1’i tek-tırnak, $Metin2’yi çift tırnak işareti içinde tanımlayın ve programı tekrar çalıştırın. Ne değişti? Hiç bir şey.
Bu duruma bakarak, ilk görüşte Perl’de tek tırnak işareti ile çift tırnak işaretinin farkını önemsememek mümkündür. Fakat bu ilerde büyük hatara yol açabilir. Tekrar özetlersek (bu sayfanın köşesini kıvırsanız iyi olur!)B tek tırnak işareti içindeki herşeyi aynen yazadırır; çift tırmak işareti içindeki değişkenlerin değerlerini, özel işaretlerin de temsil ettikleri karakterlerin yazılmasını sağlar.
Yukarıdaki programı şöyle değiştirebilirsiniz:
$Metin1 = ‘Sana da merhaba, ey ademoğlu!’;
print ‘Merhaba Dünya... $Metin1’;
Programı çalıştırın. Güzel! Değişkenin değerini değil adını okumuş olmalısınız:
Merhaba Dünya... $Metin1
Programınızda print() fonksiyonundaki tek-tırnak işaretlerini çift tırnak yapın ve yeniden çalıştırın:
$Metin1 = ‘Sana da merhaba, ey ademoğlu!’;
print ‘Merhaba Dünya... $Metin1’;
Merhaba Dünya... Sana da merhaba, ey ademoğlu!’
Çift tırnak işaretinin bir diğer marifeti, içindeki özel karakter simgelerinin yerine bu karakterleri koymasıdır:
$Metin1 = ‘Sana da merhaba, ey ademoğlu!’;
print “\$Metin1 = $Metin1”;
Burada Perl’ün ekrana yazdığı “$Metin1” kelimesi aslında bizim değişkenimizin adı değil, ekrana yazdırdığımız özel Dolar işareti ile Metin1 kelimesinden ibarettir:
$Metin1 = Sana da merhaba, ey ademoğlu!
Ekrana tek veya çift tırnak yazdırmak için de \’ ve \” işaretlerini kullanmanız gerekir. Fakat bu bir süre sonra epey zahmetli olmaya başlar. Perl, bizi bundan da kurtarabilir. Bunu içinde özel karakterler olan metnimizi q/.../ ve qq/.../ işaretleri arasına alarak yapabiliriz:
$Metin1 = q/Bu metnin içinde özel işaret (%, &, $) ‘ ve “ bulunuyor./;
Burada q/.../ ile qq/.../ tıpkı tek tırnak-çift tırnak farkına yol açar:
$Metin1 = “Merhaba Dünya!”;
$Metin2 = qq/$Metin1.. Sana da merhaba evlad!/;
q ve qq işaretlerinden sonra sınırlayıcı olarak “/.../” işareti gibi parantez “(...)”, köşeli parantez “[...]”, süslü parantez “{...}” ve büyüktür-küçüktür “<...>” işaretlerini kullanabilirsiniz. Burada dikkat edilecek nokta başta kullandığınız işareti sonda da kullanmaktır.
//////////////////////////////KUTU///////////////////////////
Uzuuuuun metin
Perl’ün sizi çok uzun metinleri tırnak işareti içine almaktan kurtaran bir kolaylığı vardır; bunu << işareti ve bir sınırlama String’i ile yapabiliriz:
$Uzuuun_metin = <<"uzun_metin";
Insanoğluna en çok güç veren unsurların başında sevilmek gelir. Fakat kişinin sevildiğini kabul etmesi zordur; hele herşeyin çıkara dayandığı çağımızda, karşılıksız sevgiyi görünce tanımak, tanıyınca kabul etmek hiç de kolay olmuyor. --Immanuel L'Avanger
uzun_metin
print $Uzuuun_metin;
Burada $Uzuun_metin değişkenin adı, “uzun_metin” ise sınırlama String’idir. Snırlama String’ini uzun metnin hem başında, hem de sonunda kullanıyoruz. Sınırlama String’ini tek tırnak içine alırsanız, diğer yöntemlerde tek tırnak kullandığınız durumlardaki gibi, metnin içinde değişken adı ve özel karakter kullanamazsınız; sınırlama değişkenini çift tırnak içine alırsanız, uzun metnin içinde değişken adı kullullanılırsa. Perl onun yerine değişmenin değerini koyar.
///////////////////////////////KUTU BİTTİ///////////////////////
Metin Biçimlendirme
Perl’de metin içeren değişkenlerle özellikle print() fonksiyonunda kullandığımız tek ve çift tırnak işaretlerinin ilişkisini ayrıntılı olarak görmenin ne kadar yararlı olduğu birazdan belli olacak. Şimdi metinler ve metin içeren değişkenlerle neler yapabileceğimize bakabiliriz. Herşeyden önce, Perl, metinlerle dört işlem yapmanıza izin verir; ama bu dört işlem aritmetikten biraz farklı sonuç verir:
Toplama: Daha önce değindiğimiz metin düzenleme araçlarından biri, iki String’i birbirine eklemekte kullandığımız nokta (.) işareti idi. (Örnek: print “kara” . “deniz”) Bu imkandan sabit metinlerle değişkenleri birleştirmekte yararlanabiliriz.
print “Bu sayfa $tarih” . “\’de güncelleştirildi!”
Çarpma: Perl’ün metin toplama fonksiyonu nokta işareti ise, metin çoğaltma fonksiyonu da çarpma (x) işaretidir. Perl’de bu fonksiyona tekrarlama (Repetition) denir. (x’in, küçük harf olmasına dikkat edin) Örnek:
print “Merhaba Dünya..” x 10
Çıkartma: Genellikle disklerdeki dosyalardan alacağımız metinlerin son satırında yeni satır (Enter, Return) karakteri bulunur. Bu, aldığımız metni HTML etiklerinin içine yerleştirirken bize zorluk verir. Perl bunun için bir String’in son karakterini kesip atmayı sağlayan özel iki fonksiyona sahiptir. “chop()” fonksiyonu, metnin sonundaki bir karakteri keser:
$yedi_harf = “ABCÇDEF”;
$giden_harf = chop($yedi_harf)
print “\$yedi_harf\’de altı harf kaldı: $yedi_harf. \$giden_harf= $giden_harf”;
Perl 5’de aynı işlevi yapan “chomp()” fonksiyonu ise, bir önceki göre daha akıllıdır; kimi dosyalarda yeni satır+satırbaşı karakterlerinin iki karakterlik yer tuttuğunu bilerek, ne kadar karakter attacağına kendisi karar verir. chop yerine chomp kullanmak daima daha güvenlidir.
Transformasyon: Herhalde metinlerle dört aritmetik işlemden bölmeyi yapamıyor diye Perl’e kızmazsınız. Perl’ün buna karşılık değişkenlerin gerçek içeriklerini değiştirme marifeti vardır. Tam içeriklerini değilse bile harflerinin biçimini! Ve sadece Perl 5’den itibaren!
Bir metin büyük harf olabilir; küçük harf olabilir. Bir metnin birinci harfi büyük olabilir; küçük olabilir. Perl değişkendeki biçimi ne olursa olsun, metinlerinizi sizin isteğinize göre büyük harf veya küçük harf yapabilir.
lc() fonksiyonu değişken içindeki biçimi ne olursa olsun, bütün String’i küçük harf (lower case) ve uc() fonksiyonu ise bütün String’i büyük harf (upper case) yapar.
////////////////////////////KUTU//////////////////////////////

Logged
 
TRForumcu.NeT | Bilgi ve Paylaşım Platformu
Gondolin
Bölüm Sorumlusu
*


Mesaj : 1.169
Forum Para : 7896.00 YTL
« Yanıtla #8 : 02 Mayıs 2008, 11:07:16 »

Lower ve Upper Kasalar
İngilizce’de büyük harfe Upper Case, küçük harfe de Lower Case dendiğini daha önce de duymuş olmalısınız. Upper Case, (üst kasa), eski matbaacılıkta büyük harflerin durduğu üst kasanın, Lower Case ise küçük harflerin durduğu alt kasanın adıydı. Buradan dile geçen bu tanımla bugün Perl dahil birçok programlama diline kadar gelmeyi başardı.
////////////////////////KUTU BİTTİ/////////////////////
lcfirst() fonksiyonu String’in sadece birinci harfini küçük harf yapmaya zorlar; ucfirst() ise sadece birinci harfi büyük harf yapar. Örnek:
$kucuk_harf = “abcdef”;
$buyuk_harf = “GHIJKLM”;
print uc($kucuk_harf);
print lc(buyuk_harf);
print lcfirst($buyuk_harf);
print ucfirst(kucuk_harf);
Bu program sırasıyla şu sonuçları verir:
kucuk_harf = “ghijklm”;
$buyuk_harf = “ABCDEF”;
$kucuk_harf = “gHIJKL”;
$buyuk_harf = “Abcdef”;
Metin biçimlendirme işleri sırasında bize gereken bazı bilgiler olabilir. Bunların başında String’in uzunluğu gelir. Bunu, String’i tutan değişkenin boyutunu linght() fonksiyonu ile sorgulayarak öğreniriz:
$Metin1 = “Dostluklar çicek gibidir, daima bakım ister!”:
print length($Metin1);
Bu program şu sonucu verir:
44
Bazen bir karakterin sayısal değerini bilmek isteriz. Bunu, ord() fonksiyonu ile sağlarız. Örneğin, K karakterinin sayısal değerini öğrenmek için:
print ord(‘K’);
şu sonucu verir:
75
Aşağıda metin biçimlendirme işlemleri yaparken ihtiyaç duyacağımız bir başka bilgi, bir String’in içinde belli bir konumdaki karakterlerin değeri olabilir. Perl, adını verdiğiniz değişkenin içindeki değeri bulur; o değerde, belirttiğiniz bir konumdan sonra belirttiğiniz sayıdaki karakterin (sub-String’in, String’in bir bölünümünün) ne(ler) olduğunu söyler. Bu bilgiye dayandığımız işlemleri sonra göreceğiz; ama şimdi sadece bunu sağlayan substr() fonksiyonun kullanımını görelim:
$Metin1 = “Bana dostunu söyle; sana kim olduğunu söyleyeyim!”:
print substr($Metin1, 3, 12);
Bu program ekrana “a dostunu sö” yazdıracaktır. substr() fonksiyonunun birinci argümanı içinde arama yapacağımız değişkenin adı, ikinci argümanı aramaya başlanacak karakter poziyonu (Dikkat! Perl saymaya 0’dan başlayacaktır!), ve son argüman bu pozisyon dahil, kaç karakterin belirleneceğini gösteren sayıdır. Buradaki örnekte, Perl’e $Metin1 değişkeninde 3’nci karakterden (‘Bana’ kelimesinin son a harfi) itibaren 12 karakterin neler olduğunu sormuş oluyoruz.
Metin düzenleme konusunda sık sık başvuracağımız split(), chop(), chomp(), shift(), unshift(), pop() ve push() fonksiyonlarını daha önce ele almıştık.
Biraz da Matematik
“Ben zaten matematikten kurtulmak için programcı olmuştum!” diyorsanız, belki de hayatta size uygun tek programlama dili Perl sayılır. Bundan, “Perl de matematikten hoşlanmaz!” sonucunu çıkartmayın; tersine matematikle ilgili bütün işleri Perl halleder; size sadece sayıları vermek kalır. Başka programlama dillerinde, bir değişkene atayacağınız sayının türünü, tam sayı mı, kesirli sayı mı olduğunu belirtmeniz gerekir. Perl için, sayı, sayıdır.
Perl, dört işlemi başarıyla yapar. Bunun için sayıların veya sayı tutan değişkenlerin arasında, toplama, çıkartma, çarpma ve bölme için sırasıyla +, -, * ve / işaretlerini kullanırız.
Diğer bütün diller gibi, Perl’de de matematik işlemler soldan sağa doğru sıra ile yapılır. Yani, “10 + 3 * 2 / 4” komutu, Perl için şu anlamı taşır:
10 ile 3’ü topla, elde ettiğin sayıyı iki ile çarp; elde ettiğin sayı dörde böl.
Fakat sizin istediğiniz daima bu sıraya uygun olmayabilir. Eğer önce 10 ile 3 toplansın, sonra 2, 4’e bölünsün ve elde edilen iki sonuç birbiri ile çarpılsın istiyorsanız, sonuç çok farklı olacaktır. Perl, matematik işlemlerini istediğiniz sırayla yapsın istiyorsanız, işlemleri parantez içine almalısınız. Örneğin, verdiğimiz örnek şöyle yazılabilir:
(10 + 3) * (2 / 4)
Perl ile bir sayının başka bir sayı ile üssünü almak için ** işaretini kullanırız: 5’in 5’nci kuvvetini bulmak için “5**5” yazmanız yeterli.
Perl bir bölme işleminin kalanını (modulo) bulabilir. 10’un 3’e bölünmesinde kalan sayıyı bulabilmek için “10 % 3” yazar ve bunu bir değişkene atarsanız, değişkenin değeri 1 olur.
Perl, bir sayının önünde eksi işaretini görünce o sayısı negatif yapar; negatif bir sayının önünde eksi işareti görünce de pozitif yapar.
Perl’e bir değişkenin tutuğu sayı ile işlem yaptırtabilir ve sonucu yeni değer olarak aynı değişkende tutmasını bildirebilirsiniz:
$sayi1 = $sayi1 * 2; veya $sayi1 *= 2;
$sayi1 = $sayi1 + 2; veya $sayi1 += 2;
$sayi1 = $sayi1 – 2; veya $sayi1 -= 2;
$sayi1 = $sayi1 / 2; veya $sayi1 /= 2;
Perl’de bir değişkenin tuttuğu değeri 1 arttırma veya 1 eksiltme içzin özel bir deyim vardır;
$sayı1 ++;
değişkenin değerini 1 arttırır;
$sayı1 --;
değişkenin değerini 1 eksiltir.
(Ve şimdi Perl’den sonra öğrenmeye karar verdiğiniz C++ ile C dilleri arasındaki farkı ve uzun uzun süre bilgisayarla aynı odada kalmanın kişinin mizah gücüne etkisini öğrenmiş bulunuyorsunuz!)
/////////////////////KUTU////////////////////
++’nin garip oyunu
Diyelim ki elinizde değeri 10 olan $Sayı1 değişkeni var. Perl’e “$Sayı1’i 1 arttır ve bulacağın değeri $Sayı2’ye ata!” demek istiyorsunuz. Bu deyimi:
$Sayı2 = $Sayı1++
şeklinde yazarsanız, $Sayı1, 11 olur; ama $Sayı2’ye 10 değeri verilir.
Bunu önlemek için bu deyimi şöyle yazmanız gerekir:B
$Sayı2 = ++$Sayı1
////////////////////////KUTU BİTTİ////////////////////
Perl’ün sayılarda kullanabileceğiniz bazı diğer fonksiyonları vardır:
Karekök: sqrt()
Logaritma: log()
Mutlak sayı: abs()
Bölme işleminin tam sayısı: int()
Bunları birarada sınayabileceğiniz bir örnek program şu olabilir:
$sayi1 = 210;
print "$sayi1\'in karekökü : ". sqrt($sayi1);
print "<p>\n";
print "$sayi1\'in logaritması : ". log($sayi1);
print "<p>\n";
print "e’nin $sayi1 ‘e eksponensiyeli: ". exp($sayi1);
print "<p>\n";
$sayi2 = -$sayi1;
print "\$sayi2 = $sayi2";
print "<p>\n";
print "$sayi2\'in mutlak değeri : ". abs($sayi2);
print "<p>\n";
$sayi3 = $sayi1 + 0.4567;
print "\$sayi3 = $sayi3";
print "$sayi3\'in integer’ı : ". int($sayi3);
Perl matematik sever dedik, değil mi? Fakat Perl, sayı ile metnin toplanmayacağını bilmez! Bu ikisini toplar; fakat elde ettiği sonucu artık sayı saymaz:
$Sayi1 = 12345;
$Metin1 = “Zor dostum, zor!”;
$Sayi1 = $Sayi1 . $Metin1;
print $Sayi1;
Biraz önce toplanabilir, çıkartılabilir bir sayı olan $Sayi1, artık bir String’den ibaret ve değeri “12345Zor dostum, zor!” olmuş bulunuyor.
Peki; böylece metinlerle uğraşmanın yollarından bir kısmını öğrendik. Fakat elimizde metin yok. Çünkü henüz Perl’e “Git bu benim C: adlı sabit diskte, Belgelerim dizinindeki filanca isimli dosyayı, al gel bakalım; gelirken bir de sade kahve söyle!” demeyi bilmiyoruz. Şimdi bunun nasıl yapılacağını öğrenelim, ki Internet’teki Form’umuzdan alacağımız bilgileri, örneğin ziyaretçi defterimize yazılan yazıları, diske kaydettirebilelim. Dosya açmayı ve Perl’e okumayı-yazmayı öğrettiğimizde kullanacağımız bir iki fonksiyon daha var ki, onları daha sonra göreceğiz. Burada sadece bu fonksiyonların bir metinrde arama, bulma ve değiştirme işlevleri olduğunu belirtmekle yetinelim.
Perl’de Dosya İşlemleri
İlk öğrendiğiniz dosya işlemi, eğer DOS döneminden beri PC ile uğraşıyorsanız, “dir” komutu idi. Akıp giden bir takım listelerle, sabit diskin içindeki “şeyleri” görebilirdik bu komutla. Sonra Windows, önce File Manager (Dosya Yönetici) ile, sonra Windows Explorer (Windows Gezgini) ile sabit disk ve disketlerimizin içindekileri, çeşitli simgelerle ekrandaki bir takım pencerelerde görüntüler oldu. Unix dünyasında, örneğin Linux’ta DOS’un “dir” komutunun yaptığı işlevi “ls” komutu ile yapatırabiliriz; fakat artık Unix bilgisayarları da XWindow ile görsel kullanıcı arabirime sahip oldu; orada da dosyal işlemlerini Mouse işaretçisiyle tıklayarak yapabiliriz. MacOS ise, tasarlandığı birinci günden değilse bile ikinci günden beri dosya işlemleri için grafik arabirimi kullanıyor.
Dolayısıyla, kişisel bilgisayarda dosya işlemleri dediğimiz zaman, aklımıza çoğunlukla “tıklamak,” “sürüklemek” ve “bırakmak” geliyor. Bizim için adeta düşünmeden yapılabilen bu işleri Perl’e yaptırabilmek için, disk kayıt sistemini biraz yakından tanımamız gerekir.
“Dosya,” sabit veya takılıp-çıkartılabilen bir disk (veya CD-ROM) üzerinde, kayıt yapılabilir bir ortama, başladığı ve bittiği yer belirtilerek, belirli bir sisteme göre ve byte birimiyle yapılmış kayıt demektir. Her bir kaydın başladığı ve bittiği yer ve bu ikisinin arasındaki kaydın ne adla anılacağı yazılır. Böylece “Askerlik Mektubu.doc” adlı kaydın, arandığı zaman nerede bulunacağı bilinir.
//////////////////KUTU///////////////////////
Biraz Unix Bilgisi
Unix işletim sisteminde sadece disk/disket/CD-ROM’da kayıtlı byte’lara dosya denmez; klavyeden gelmekte olan, okunmakta olan bir sabit diskten alınan, veya bilgisayara iletişim kapılarından (Com Port’lar veya ağ kartları) girmekte olan veya ekran ve iletişim kapılarından çıkmakta olan veri de dosya sayılır; bu özel dosyalara “Standart Girdi/Çıktı” (Standart Input/Output) dosyası denir. Bu dosyalar üçe ayrılır:
Standart Girdi (STDIN) dosyası: Tanım itibariyle klavyeden bilgisayara ulaşmakta olan bilgi akımıdır. Klavyeden bir programa yönelik olarak yazdığınız herşey Standart Input sayılır.
Standart Çıktı (STDOUT) dosyası: Bilgisayarın ekranına gönderilen, dosyaya yazılmak yerine ekrana yazılan her türlü bilgi akımıdır.
Standart Hata (STDERR) dosyası: İster ekrana, ister diske gönderilebilecek bilgi akımıdır. Unix işletim sistemlerinin büyük bir bölümü bu bilgileri sabit diskte dosyaya yazarlar.
Unix sistemleri, bu üç dosyayı kullanarak bir programa veri verebilir veya veri alabilirler.
//////////////////////////KUTU BİTTİ/////////////////////
İşletim sistemi ne olursa olsun, dosyaları iki ana bölüme ayırırız: İnsan tarafından okunabilen dosyalar; sadece makina tarafından okunabilen dosyalar. Düzyazı dosyaları, .INI dosyaları, .CONF dosyaları, herhangi bir düzyazı programı ile açılıp, okunabilir. Okuduğunuz şeyden anlam çıkmaması veya anlaşılır harf olarak görüntülenmeyen bir-iki karakter bulunması dosyanın yazı dosyası olma niteliğini değiştirmez. Makina tarafından okunabilir veya binary (ikili) dosyalar ise programlar tarafından okunabilir. Örneğin uzatması EXE olan bir dosyayı işletim sistemini oluşturan programlar okur. Boyutu küçük bir EXE dosyasını sürükleyerek Not Defteri’nin içine bırakırsanız, bu tür dosyaların nasıl bir içeriğe sahip olduğunu görebilirsiniz. (Dikkatli olun, çok büyük dosyalar Not Defteri’nin çökmesine yol açar; açtığınız dosyayı sakın kaydetmeye kalkmayın!)
Perl’e, düz yazı dosyalarını okutabilirsiniz.
Dosyayı Açalım!
Perl açısından bir dosyanın okunması, yazılması veya dosyaya ek yapılması için önce açılması gerekir. Bu, işletim sistemlerinin programlara, dillere ve kullanıcılara getirdiği bir zorunluktur. Perl, hangi işletim sisteminde çalışıyorsa, o sistemin dosya açma yöntemini bilir ve uygular. Bize düşen sadece Perl’e dosyayı açmasını bildirmektir.
Perl’ün ister okumak, ister yazmak, ister eklemek amacıyla olsun, bir dosyayı açmasını open() fonksiyonuyla sağlarız. Bu fonksiyon iki argüman alır:
1. Dosyanın Perl tarafından kullanılırken alacağı ad: Handle. Kelime anlamı kulp, tutacak yer, tutamak, sap anlamına gelen bu ada, başka kaynaklarda belirteç dendiğini görebilirsiniz. Dosya adı ne olursa olsun, Perl, bu dosyadan alacağı bilgi akımını vereceğiniz bu kelime ile tanıyacaktır. (Daha teknik ifade edersek, Unix sisteminde açılan bir dosya, dosya sisteminde özel bir nitelik kazanır. Ona bu niteliğini veren, içindeki verinin sisteme alınacağı yolun oluşturulması; dosyanın sabit diskte başkası tarafından silinmesi veya değiştirilmesine karşı önlem alınması gibi sistem-varî hazırlıkların yapılmasıdır.)
2. Dosyanın adı: Sabit disk sisteminde dosyanın arama yolu (path) ile birlikte adı.
IRC Server’lara ve Chat ortamına aşina olanlar için Handle veya Perl açısından dosyanın içeriğini belirleyen adı, Nick’e benzetebiliriz. Hepimizin bir adı soyadı olduğu halde Chat ortamında herkesin bir Nick’i bulunur. Adımız ne olursa olsun IRC’ye bağlandığımız andan itibaren, bu Nick ile biliniriz.
Dosya, çalışmakta olan Perl ile aynı dizinde ise, dosya adının önüne arama yolu koymaya gerek yoktur. Ancak dosya başka dizinde ise Perl’ün dosyayı nerede arayacağını bilmesi gerekir. Diyelim ki, Perl programının bulunduğu dizinde, “ornek.txt” adlı bir düzyazı dosyamız var; bu dosyayı Perl’e açtırmak istiyoruz:
open (DOSYA, ‘ornek.txt’);
Burada open() fonksiyonuna, “ornek.txt” dosyasını açmasını ve bundan böyle bu dosya ile ilgili işlemlere “dosya” adıyla gönderme yapacağımızı söylüyoruz. Bu dosya, Perl ile aynı dizinde değil de, uzaklarda bir yerde olabilirdi:
open (DOSYA, “../../metinler/duzyazilar/ornek.txt”);
//////////////KUTU/////////////////////
Path!
Sabit diskinizdeki arama yolu (Path) ile ilgili yazım kuralları, Web sitesine gelince biraz değişir.
Kişisel Web Server’da Web sitenizin mutlak “root” (kök dizini) adresini bilmeniz kolay. Bu, örneğin c:\inetpub\wwwroot gibi bir dizin olmalı. Fakat bir evsahibi firmadan (Host) edindiğiniz Web Sitesinin mutlak arama yolunu bilemezsiniz. Benzeri zorluklar ve güvenlik önlemleri yüzünden Web Server, CGI programları için dosya arama yolunu mutlak değil göreli olarak kullanılması zorunluğunu getirir. Bu, herşeyden önce bütün dosyaların Web sitesinin bulunduğu sabit diskin kök dizinine olmasını göre belirtilmesini gerektirir. Örnek olarak herhangi bir www.örnek_site.com.tr’nin iskeletinde, sözgelimi çalışmakta olan “oku_yaz.pl” isimli CGI programı ile bu programın açmak istediği “ornek.txt” dosyasının birbirine göre yerinin şöyle olduğunu düşünelim:
<cgi-perl.013.tif>
Buna göre, open() fonksiyonunda dosyanın arama yolunu iki türlü belirtebiliriz:
1. Mutlak: “/Belgelerim/duzyazılar/ornek.txt
2. Göreli: “../duzyazılar/ornek.txt
ornek.txt, Web alanı dışında olduğu için, hiç kimse bu dosyanın URL (Internet adresini) Browser’ının adres hanesine yazarak, bulamaz; çünkü bu dosyanın Webb alanında olmadığı için URL’i olamaz.
///////////////////////////KUTU BİTTİ///////////////
Dosya adlarının programlama yoluyla (programmatically) verilebileceğini doe belertelim. Diyelim ki, dosya adını tutan bir değişkeniniz var. Bu değişkenin bu değeri nasıl edindiği şimdilik önemli değil. Sözgelimi bu adı Web sitemizi ziyaret eden kişinin bir tercihi belirleyebilir; veya biz değişkene bu değeri atayabiliriz:
$dosya_adi = ‘ornek.txt’;
open (GIRDI, $dosya_adi);
Şimdi artık Perl bu dosya ile istediğiniz her türlü okuma, yazma ve ekleme işlemini yapabilir. Bununla birlikte Perl ile dosyalarda yapabileceğimiz işlemleri bilirsek, dosya açma işleminin boyutunu daha iyi anlayabiliriz:
////////////////////KUTU//////////////////////
Tutamak adı neden büyük harf!
Perl geleneğinde file handle, açtığınız dosyaların Perl tarafından tanındığı adlar, değişken adı kurallarına uymak zorundadır: rakamla başlayamaz; harfle veya alt-çizgi ile başlar; içinde rakam bulunabilir; işaret bulunamaz. Fakat hemen hemen bütün profesyonel Perl programlarında HANDLE’ın daima büyük harfle yazıldığını göreceksiniz; bu kesinlikle zorunlu değildir.
Tutamak adları, tamamen keyfî olmakla birlikte anlamlı olmalı; programınızı kullanacak veya kendi programına katabilecek kişilerin program akışını anlamalarına imkan vermelidir.
////////////////////////////////////////////////////
Dosya Okuma: Okumak, bir dosyanın içeriğini değiştirmeden içindeki verileri almak ve kullanmak demektir. Bir dosyanın okunmak için açılması için, varolması gerekir. olmayan bir dosya okunmak için açılamaz.
Dosya Yazma: Bir dosyaya yeni bilgi girmek için açmak, yazmak amacıyla açmaktır. Olmayan bir dosyayı, yazmak amacıyla açmak, dosyayı oluşturmak demektir. Varolan bir dosyayı açar ve yazarsanız, dosya silinir ve yeniden yazılır.
Dosyaya Ekleme: Ek yapmak amacıyla açılan dosyanın sonuna yeni veri kaydedilir. Ekleme, mevcut dosyayı silmez; varolan dosyanın içeriğini değiştirir. Olmayan bir dosyayı ek yapmak için açmak, gerçekte yazmak için açmakla aynıdır.
Bir dosya, bu üç işlemden sadece birisi için açılabilir; yani bir dosyayı, hem okumak, hem de yazmak için açamazsınız. Perl’e bir dosyayı ne amaçla açtığınızı söylemeniz gerekir. Bunu, dosya adının önüne koyduğumuz büyüktür-küçüktür işareti ile yaparız: “<” oku; “>” yaz; “>>” ekle! Örnekler:
open (OKU, ‘mevcut.txt’);   #Okumak için
open (OKU, ‘<mevcut.txt’);   #Okumak için
open (YAZ, ‘>yeni.txt’);   #Yazmak için
open (EKLE, ‘>>mevcut.txt’);   #Ek yapmak için
Burada okumak amacıyla dosya açarken, dosya adının önüne işaret koymayabileceğimizi görüyorsunuz. Bu imkana rağmen, iyi bir Perl programlama geleneği okumak için bile açsanız, her dosyanın adının önüne amacınızı belirten işareti koymaktır. Dosya tutamakları da dosyanın okunmak amacıyla mı, yoksa yazılmak amacıyla mı açıldığını belirtebilir.
Daha sonra open() fonksiyonuyla birlikte kullanmak üzere bir değişkene değer olarak dosya adı verirken de dosyanın açma amaçı işaretini koyabiliriz:
$dosya_adi = ‘>ornek.txt’;   #Yazmaya hazırlık
open (CIKTI, $dosya_adi);   #Bu dosyaya yazılabilir
/////////////////KUTU///////////////////
Dosya Açamayan Perl Ölsün Mü?
open() fonksiyonu, başarıyla sonuçlandıysa, programa True (doğru) sonucunu verir; başarısızlıkla sonuçlanırsa False (Yanlış) sonucunu. open() fonksiyonunun başarısızlıkla sonuçlanması, okumak üzere açmak istediğiniz bir dosyanın verdiğiniz yolda bulunamaması, yazmak veya eklemek üzere açtığınız bir dosyanın salt-okunur olması gibi sebeplerden kaynaklanabilir.
open() fonksiyoru hata verirse, bu kullanarak programı durdurabiliriz. Bunun klasik örneği şudur:
$dosya_adi = ‘>ornek.txt’;   #Yazmaya hazırlık
open (DOSYA, $dosya_adi) or die “Yazmak için $dosya_adi açılamıyor. Program zorunlu olarak sona erdi.\n”;
Buradaki “or die” fonksiyonu “ya dosyayı aç, veya öl!” anlamına geliyor; ve Perl’e dosyayı açamazsa, bir mesaj vererek durmasını bildiriyor.
Bu yöntem bir rapor yazma dili olarak Unix sisteminde kullanıldığı zaman Perl’ün hatalı bir durum oluştuğu halde çalışmaya devam etmesini önlemesi bakımından iyi bir yöntemdir. Fakat Perl’ü, CGI programı olarak çalıştırdığımız zaman Server’daki Perl’ün durması, ziyaretçilerimiz açısından hiç bir anlam taşımaz. Tersine Perl’ün durması değil; hatayı anlayarak ziyaretçiye uygun bir karşılık vermek ve yeni seçenekler sunmak üzere çalışmaya devam etmesi gerekir.
Dolayısıyla, ilkelerini sonra görmek şartıyla, bu deyimi şöyle yazabiliriz:
$dosya_adi = ‘>ornek.txt’;   #Yazmaya hazırlık
open (DOSYA, $dosya_adi) || &Hata;
Burada, open() fonksiyonunun hata vermesi halini düzenleyen (or/veya) işlemcisi olan “||” işareti ile bir Subrutin (programcınının yazdığı fonksiyon) kullandığımıza dikkat edin. Subrutin meselesine geleceğiz; fakat şimdilik “Hata” adlı ve Perl programının sonuna koyacağımız Subrutin’nin kodunu vermekle yetinelim:
sub Hata {
print “Bir hata oldu; dosya açılmıyor. Ya bu dosya yok, ya da biz Perl’ü yazarken bir hata yaptık!\n”;
print “Çok özür dileriz.. Şurayı tıklayın da bari başka bir tarafa gidin!\n”;
print “<A HREF=\”baska_bir_taraf.htm\”>Tıklayın!</A>\n”;
exit
}
///////////////////KUTU////////////////////////
Her sistemin kendi diline göre
Perl ile yazacağınız CGI programları, çalıştıkları işletim sistemi ortamına göre dosya araya yolu vermek zorundadır. Unix veya NT tabanlı Web Server’lar için, arama yolu URL tarzında olmalıdır. Ancak Perl programınıza kendi sabit diskinizde dosya açtırma denemesi yaptırıyorsanız, bu işletim sistemi göre değişir:
95/98/NT/2000:
open (DOSYA, “>C:\Belgelerim\Veriler\Metinler\ornek.txt”);
MacOS:
open (DOSYA, “>Ana:Belgeler:Veriler:Metinler:ornek metin”);
Linux:
open (DOSYA, “>/usr/home/belgeler/Veriler/metinler/ornek.txt”);
Bu sistemlerde mutlak arama yolu yerine göreli (çalışmakta olan Perl dosyasına göre) yol da belirtebilirsiniz:
95/98/NT/2000:
open (DOSYA, “>..\ornek.txt”);
MacOS:
open (DOSYA, “>::ornek metin”);
Linux:
open (DOSYA, “>../ornek.txt”);
///////////////////KUTU BİTTİ//////////////
/////////////////KUTU////////////////////

Logged
 
TRForumcu.NeT | Bilgi ve Paylaşım Platformu
Gondolin
Bölüm Sorumlusu
*


Mesaj : 1.169
Forum Para : 7896.00 YTL
« Yanıtla #9 : 02 Mayıs 2008, 11:07:51 »

Açtığınızı Kapatın!
Açtığınız dosyayı kapatmanız gerekir. Bunun için programda yapılacak bütün dosya işlemlerinin bittiği yere şu fonksiyonu yazmanız yeter:
close(TUTAMAK);
Burada TUTAMAK kelimesinin yerine dosyayı açarken verdiğiniz tutamak adını yazacaksınız. Dosyayı kapatmazsanız ne olur? Hiç bir şey olmaz; Perl, program bitince dosyayı kapatır. Fakat bir dosyayı ne kadar çabuk kapatırsanız, o kadar iyi: çünkü Perl dosya için close() fonksiyonunu icra etmedikçe, veya kendisi dosyayı zorunlu olarak kapatmadıkça, bellekteki bilgileri dosyaya yazmaz. Bu sırada Server çökebilir; dosya son bilgilerle güncelleştirilmemiş olur. Bu sırada başka bir program dosyayı açmak isteyebilir; dosya eksik olarak sunulur. İyi programcılık tekniği, işi biten dosyanın hemen kapatılmasını gerektirir.
////////////////////KUTU BİTTİ////////////////////////////
Dosyayı Okuyalım
Çok güzel! Perl’ü öldürmeden dosyayı açmayı başardık! Şimdi sıra Perl’e dosyadaki yazıyı satır satır okutmakta. Fakat bu çok kolay. open() fonksiyonunda belirttiğiniz dosyanın tutamağını (belirteç’ini, Handle’ını, Nick’ini!) büyüktür-küçüktür işaretleri arasında ve herhangi komutun veya fonksiyonun parçası veya argümanı olarak belirttiğiniz anda, Perl, iki eli kanda olsa, gider ve dosyadan bir satır okur; gelir!
Bu cümle biraz karışık oldu. en iyi örnekle anlatalım. Yukarıda ornek.txt dosyasını, Perl’e “DOSYA” tutamağıyla açmasını bildirdik. Şimdi Perl’e bu dosyadan bir satır okutalım. Bunun için önce kendinize bir ornek.txt dosyası yapmanız ve bunu Perl dosyasının çalıştığı dizine koymanız; farklı dizine koyacaksanız open() fonksiyonunu yazarken, yukarıda öğrendiğimiz şekilde, doğru arama yolu belirtmeniz gerekir. Benim ornek.txt dosyamın birinci satırında şunlar yazılı:
Bu bir örnek düz yazı dosyasıdır. Bu dosyanın içinde bir çok bilgiler yer alıyor.
Sonra açın Not Defteri’ni (veya herhangi bir düzyazı programını) vey şu kodu yazarak dosya01.pl adıyla kaydedin:
print "HTTP/1.0 200 OK\n";
print "Content-Type: text/html\n\n";

print "<HTML>\n";
print "<HEAD>\n";
print "<TITLE>Tekrarlama</TITLE>\n";
print "<meta http-equiv=\"content-type\" ***********\"text/html; charset=ISO-8859-9\">\n";
print "<meta http-equiv=\"Content-Type\" ***********\"text/html; charset=windows-1254\">\n";
print "</HEAD>\n";
print "<BODY>\n";
print "<H4>Dosya Aç</H4>\n";
print "<p>\n";
open (DOSYA, "<ornek.txt") || &Hata;
$satir1 = <DOSYA>;
print $satir1;
sub Hata {
print "Bir hata oldu; dosya açılmıyor. Ya bu dosya yok, ya da biz Perl’ü yazarken bir hata yaptık!\n";
print "Çok özür dileriz.. Şurayı tıklayın da bari başka bir tarafa gidin!\n";
print "<A HREF=\"baska_bir_taraf.htm\">Tıklayın!</A>\n";
exit
}
print "</BODY>\n";
print "</HEAD>\n";
print "</HTML>\n";

Bu kodda, okumak amacıyla ve DOSYA tutamağı ile ornek.txt dosyasını açıyoruz; ve ve ilk satırını okutup; okunan metni $satir1 değişkeninin değeri yapıyoruz. Bunu hangi komut yapıyor? Büyüktür-küçüktür işareti içine alınmış olan DOSYA tutamağı yapıyor: <DOSYA>. Burada büyüktür-küçüktür işaretlerine “Dosya Girdi Operatörü” (File Input Operator) denir. Bunu izleyen satırda print() fonksiyonu, bu değişkeni ekrana gönderiyor. Bu alıştırmayı yaptı iseniz, ve dosyanın adını veya yolunu yanlış yazdı iseniz, şu anda ekranda hata mesajını görüyorsunuz! Herşey yolunda gitti ise örnek yazı dosyanızın birinci satırını görüyor olmalısınız.
<cgi-perl014.tif>
Belki ekranda belli olmuyor, ama görüntülenen sadece birinci satırdaki harfler, rakamlar ve işaretler değil, fakat aynı zamanda satırın sonundaki “yeni satır” (newline) karakteri de ekranınızda! Yani gerçekte ekranda görüntülenen metin şu şekilde:
Bu bir örnek düz yazı dosyasıdır. Bu dosyanın içinde bir çok bilgiler yer alıyor.\n
Perl’ün bir dosyadan “bir satır” yazı okuyabilmesi için yeni satır karakterini bulması gerekir. Bu Perl’ün “satır” saydığı veriyi tanımlamasını sağlar. Hatırlarsanız, bu karakteri chomp() fonksiyonu ile atabiliyoruz!
Yine hatırlarsanız, “$_” şeklinde yazılan özel bir değişkenden söz etmiş, bu değişkenin Perl’e gelen her verinin ilk uğrak yeri olduğunu söylemiştik. Birazdan, bu değişkeni kullanacağız. Şimdilik, $satir1’in değerinin $_’in değerine eşit olduğunu belirtmekle yetinelim.
Bu arada, Perl’e bir koşul gerçekleşinceye kadar, biteviye iş yaptırtma, yani döngü kurma fonksiyonlarımızdan while()’ı da hatırlıyor musunuz? Bu fonksiyon, şöyle kullanılıyordu:
while (koşul) {
....koşul;
...doğru;
...iken;
...yapılacak;
...işler;
}
koşul doğru değilse yapılacak işler;
Şimdi bunu dosya okutmakta kullanalım; ve yukarıdaki kodu biraz değiştirelim. dosya01.pl’de :
$satir1 = <DOSYA>;
print $satir1;

satırlarının yerine şu bloku yazın:
while (<DOSYA>) {
print $_;
}
Perl programını dosya02.pl adıyla kaydedin; ve çalıştırın. Şimdi ekranda örnek yazı dosyasının içeriğini tümüyle görüyor olmalısınız. Bunu sağlayan bu satırlık bölümü irdeleyelim: while() fonksiyonu verdiğiniz koşul doğru olmaya devam ettiği sürece, süsyül parantezle belirlenen kendi bloku içindeki komut ve fonksiyonları icra eder. Dosya Girdi Operatörü (yani <> işaretleri) arasına aldığınız dosya tutamağının doğru olmaya devam etmesi demek, Perl’ün dosyada okunacak yazı kalmadığına karar vermesi demektir. Dosyada okunacak yazı kaldığı sürece, Dosya Girdi Operatörü dosyayı satır satır okuyacak ve her satırı $_ değişkeninin içine yazacaktır. Perl programımız ikinci adımda bu değişkeni ekranda görüntüleyecek ve yeniden while() döngüsünün başına dönecektir. Ve bu işlem, dosyada okunacak yazı kalmayıncaya (veya teknik deyimiyle dosya sonu işaretine [EOF] rastgelinceye kadar) bu işlem devam edecektir.
Şimdi, buradaki örnekte Perl’ün okuduğu her satırı ya Perl’ün ya da bizim Tekil/Scalar değişkene koyduğumuza dikkat ediyor musunuz? Yani her yeni satır okunduğunda, bir önceki satır siliniyor! Oysa biz dosya işlemlerini çoğu zaman dosyanın tüm içeriğini alıp kullanmak amacıyla okutuyor olabiliriz. Acaba okunan her satırı bir dizi-değişkenin içine koyamaz mıyız?
Neden olmasın? dosya02.pl’deki while() blokuna ait üç satırı silin ve yerine şu üç satırı yazın:
@satirlar = <DOSYA>;
print @satirlar;

Bu kez dosyayı dosya03.pl adıyla kaydedin ve Browser’da açın. Yine dosyanın tüm içeriğini görüyor olmalısınız.
Bu kez, okuttuğunuz dosya kaybolmadı; hepsi @satirlar değişkeninin içinde duruyor. Şimdi size bir pop quiz!
1. @satirlar’ın kaç elemanı var?
2. Bu elemanları tek tek nasıl görüntüleyebilirsiniz?
(Bu soruların cevabı, bu kitapçığın materyalini oluşturan zip dosyasında, popquiz.pl dosyasında bulunabilir.)
Dosyaya Yazdıralım
Perl’ümüz bayağı gelişiyor; önce dosya açmayı öğrendi; sonra okumayı. Şimdi sıra yazmada! Böylece okur-yazar bir Perl’ümüz olacak.
Aslına bakarsanız, Perl’ye baştan beri print() fonksiyonu ile “yazdırıyoruz!” Bu ana kadar bu fonksiyonun ekranda (veya doğru değimiyle, Browser penceresinde) yazmasını sağladık; şimdi bu işlemi diskteki bir dosyaya yapmasını sağlayacağız. Bu işlemi bir dosya açtırarak, ve print() fonksiyonunu bu dosyanın tutamağına (Handle’ına) yönlendirerek yapabiliriz. Örnek:
open (CIKTI, ‘>yazilan_dosya.txt)’;
print CIKTI “Bu bir örnek satır\n”;
Bu program, ekranda hiç bir şey görüntülemez; ancak kendi çalıştığı (bulunduğu) dizinde “yazilan_dosya.txt” adında bir dosya oluşturarak, içine “Bu bir örnek satır” yazar. Bu programı çalıştırdıktan sonra oluşturulan dosyayı açarsanız, içinde bu satırın sonuna yeni satır kodunun da girilmiş olduğunu görürsünüz. Programı çalıştırdığınız anda, Perl, işletim sistemine, böyle bir dosya bulunup bulunmadığını ve varsa, açıp içindekileri değiştirme yetkisi bulunup bulunmadığını sorar.
İşletim sistemi, böyle bir dosya varsa salt okunur olup olmadığına ve Web’de paylaşım izni bulunup bulunmadığına bakar. Dosya salt okunur değilse ve paylaşılabilir nitelikte ise işletim sistemi Perl’e dosyayı açması ve içeriğini değiştirmesi için izin verir. Değilse, Perl size hata mesajı ile acıklı durumu bildirir. (Bir Web Server’da Web sitenizdeki dosyaların okuma-yazda ve çalıştırma izinlerini nasıl düzenleyebileceğinizi son bölümde göreceğiz.) Yazdırmak istediğiniz dosya yoksa ve sizin kullanıcı olarak böyle bir dosya oluşturma hakkınız varsa, Perl önce dosyayı oluşturur; sonra da içine istediğiniz yazıyı yazar.
Okumak için dosya açma alıştırmasında olduğu gibi, yazdırma amacıyla açacağınız dosyalarla ilgili olarak da programınıza hata yakalama subrutini (fonksiyonu) koymalısınız.
Peki, hazır dosya yazdırmayı öğrenmişken, biraz uzunca bir şeyler yazdıralım. Örneğin:
open (CIKTI, ‘>yazilan_dosya.txt)’;
for ($i = 998; $i < 1102; $i += 1) {
print CIKTI “$i\n”;
}
Bu programın oluşturduğu dosyayı açtığınızda muhtemelen şöyle bir dizi göreceksiniz:
998
999
1000
1001
1002
Oysa biz genellikle bu tür listelenen bilgilerin sağa hizalanmasını isteriz. Örneğin:
   95
   998
   999
   1000
   1001
   1002
////////////////////SAYFA TASARIMI İÇİN NOT://///////////////
Yukarıdaki birinci listedeki sayılar sola blok; ikinci listedeki sayılar sağa blok olacak.
/////////////////NOT BİTTİ/////////////////
Perl’e, ekrana veya dosyaya bu tür biçimlendirilmiş (formatted) veri yazdırma işlemini printf() fonksiyonu ile yapabiliriz. Bu fonksiyon, Perl’ün biçimlendirme argümanlarını kullanır.
/////////////////KUTU//////////////////////////////////
Perl’de String Biçimlendirme
printf() fonksiyonu ile ekrana veya dosyaya String yazdırırken, uygulanan yazım kuralı şöyledir:
printf(BİÇİM, LİSTE);
Örnek:
printf(“%.2F”, $Degisken);
Biçim argümanının elemanları şöyle sıralanır:
1. Biçim argümanının başladığını belirten yüzde (%) işareti
2. İşaret: Biçim argümanı beş ayrı işaret alabilir:
+   Yazılan String’in önünde artı (+) veya eksi (+) işareti olmasını sağlar
-   String’in sola hizalanmasını sağlar
0   Sayının soluna boşluk değil sıfır konulmasını sağlar
#   Heksadesimal sayılarda sola 0x veya 0X; Octal sayılarda sayıdan önce 0 konmasını sağlar.
boşluk   Pozitif sayıların önüne bir aralık konarak, negatif sayılarla hizalanmasını sağlar.
   3. Çıktı alanının asgarî boyutu.
   4. Çıktının kaç basamaklı olacağı: bir nokta bir sayı ile yazılır.
   4. Çıktı alanının türü. 15 çıktı alanı türü tanımlanabilir.
      s   String
      d   Integer, tam sayı
      f   Real, gerçek sayı
      g   Campact Real, sıkıştırılmış gerçek sayı
      u   Unsigned integer, işaretlenmemiş tam sayı
      x   Hexadecimal sayı (16-tabanlı, küçük harfle)
      X   Hexadecimal sayı (16-tabanlı, büyük harfle)
      o   Octal (8-tabanlı)
e   Scientific notation (10’un kuvveti olarak yazılmış sayı, küçük harf)
E   Scientifc notation (10’un kuvveti olarak yazılmış sayı, büyük harf)
      c   Single character (8-bit’lik karakter, değer olarak)
      ld   Long integer (32-bit’lik tam sayı)
      lu   Long unsigned integer (32 bit(lik işaretlenmemiş tam sayı)
      lx   Long hexadecimal (32-bit’lik 16-tabanlı sayı)
      lo   Long octal (32-bit’lik 8-tabanlı sayı)
Perl ile String biçimlendirmek kolay değildir. Perl’ün çeşitli işletim sistemleri için geliştirilmesi işini sürdüren kurum ve kuruluşların sitelerinde örnek String’ler ve sayılar üzerinde biçimlendirmenin hasıl yapıldığını gösteren Perl programları vardır. Bu dosyalar örnek olarak kullanılabilir. Bu kitapçığın örnek kodları arasında bulacağınız bicim.pl dosyasını çalıştırarak, biçimlendirme argümanlarının nasıl kullanıldığını inceleyebilirsiniz. Bu programda “PCWorld” String’ine, 5.242984 ve 2553 sayılarına değişik biçimlendirme argümanları ile verdiğimiz farklı şekilleri burada görüyorsunuz:
<cgi-perl015.tif>
Örneğin, “PCWorld” String’inin “PCW” olarak biçimlendirilmesi için şu programı verebilirsiniz:
$Metin1 = “PCWorld”;
printf(“%.3s\n”, $Metin1);
////////////////////////////KUTU BİTTİ//////////////////////
Yukarıdaki sayı dizinin sağa hizalanmış olarak yazılmasını sağlamak için printf() fonksiyonunu şöyle yazabiliriz:
open (CIKTI, ‘>yazilan_dosya.txt)’;
for ($i = 998; $i < 1102; $i += 1) {
printf(CIKTI “%4d, $i\n”;
}
Bu komutla rakamlarımıza asgarî dört basamaklı yer ayırtıyoruz ve tam sayı olarak yazadırıyoruz. Bu programla Perl, bütün rakamlarınızı sağa hizalayacaktır.
//////////////////KUTU///////////////////////////////
Yazdırmış olsa idik!
Perl’ün sprintf() fonksiyonu aynen printf() gibi çalışır; fakat dosyaya veya ekrana yazdıracağı veriyi istediğiniz bir değişkene değer yapmak üzere bize getirir.
$degisken = sprintf(“%4d, $i\n”);
deyimi ile tıpkı dosyaya yazılacak olan satırı $degisken’in değeri yapabiliriz.
//////////////////////////KUTU BİTTİ//////////////////////////
Dosyaya Ek Yapalım
Perl açısından bir dosyaya yazmakla, bir dosyanın sonuna metin eklemek arasında yapacağımız işlemler açısından hiç bir fark yoktur; sadece dosyanın açılışında fark vardır. Fakat bu çok önemli fark: Yazmak için açtığınız dosya varsa, varolan içeriği tümüyle değiştirilir; eklemek için açtığınız dosya yoksa oluşturulur; varsa yazdırmak istediğiniz metin en sona eklenir. Burada tekrar edelim:
Yazmak için dosya açma fonksiyonu:
open (YAZ, “>yazilacak_dosya.txt”);
Eklemek için dosya açma fonksiyonu:
open (EKLE, “>>eklenecek_dosya.txt”);
Bir kere daha vurgularsak, yazmak için dosya adının önünde tek büyüktür (>) işareti, eklemek için iki büyüktür (>>) işareti kullanıyoruz. Bu minicik işaretin işlevi arasındaki fark; aylardır biriktirdiğiniz ziyaretçi defteri girdilerinin tümünün silinip, yerine son ziyaretçinin girdilerinin yazılması olabilir!
Gerçek Form.. Gerçek Perl
Eh, artık Perl ile bir Form’daki bilgileri alıp, bir dosyaya yazdıracak düzeye geldik. Şimdi Web sitemize bir konuk defteri koyalım; bunun derleyeceği bilgileri ziyaretçiye onaylattırdıktan sonra bir dosyaya eklettirelim. Son bölümde, gerçek CGI ortamının kurallarını biraz daha yakından tanıdıktan sonra Perl programımıza, bize, bir ziyaretçinin daha konuk defterini doldurduğunu belirten bir elektronik mektup göndermesini öngören küçük bir bölüm daha ekleyeceğiz,
Kitapçığın baş tarafında “Sizi tanıyabilir miyiz?” başlıklı bir form yapmıştık ve bunu form.htm adıyla kaydetmiştik. Şimdi o dosyayı Form’un ACTION hanesine yazdığımız Perl programının adını değiştirmek amacıyla açın. Hatırlayacaksınız, o Form için yazdığımız Perl programı sadece Form’daki bilgileri Standart Girdi (STDIN) yoluyla okuyor ve bunları Browser penceresinde görüntülüyordu. Form’un ACTION hanesini şöyle değiştirin ve dosyası form2.htm adıyla kaydedin.
Aşağıda kısa bir şekilde Perl’de arama-bulma-değiştirme işlemlerine değineceğiz. Bu bölümde yer alan alıştırmalardan sonra forn_analiz.pl’i açın ve form_islem.pl adıyla kaydedin; birazdan bu programın içeriğini değiştereceğiz. Önce, gözden geçirmeyi elimizde işlenecek bir metin oluncaya kadar geri bıraktığımız bir iki metin arama-değiştirme fonksiyonunu ele alalım.
Bul-Değiştir
Başkasının yazdığı metinlerde noktalama işaretlerinden sonra boşluk bırakılmamış olmasına kızar mısınız? Ben de! Perl ile metin düzenleme fonksiyonlarından geriye bıraktığımız ikisi, vereceğimiz bir String modelini (pattern) metinde arayan ve bulduklarını değiştiren fonksiyonlarla, Perl’e okuttuğumuz metinlerde sadece yazım kurallarını uygulatmakla kalmayız, fakat Form bilgisi içinde sitemizin güvenliğini sarsıcı metin olup olmadığını tarayabiliriz; gereksiz karakterleri, örneğin yeni satır başlatan kodları atabiliriz.
Perl’ün içinde arama işlemi de bulunan split() fonksiyonunu daha önce görmüştük. Bu fonksiyona, arayacağı nesneyi iki bölü işareti (//) arasında veriyorduk; hangi değişkende aramay yapılmasını istediğimizi bildiriyorduk; elde ettiği sonuçları yeni bir değişkene yazmasını istiyorduk. Örneğin:
@Yeni_degisken = split(/\&/, $Aranan_degisken);
Bu deyimle, Perl, $Aranan_degisken adlı değişkenin içinde, & işaretlerini bulur ve değişkeni & işaretlerinden parçalara böler; elde ettiği her bir parçayı @Yeni_değişken adlı değişkenin elemanları olarak yazar.
Perl’ün arama-bulma işi yapan bir diğer işlemcisi benzerini-bul (match) “m//” operatörüdür. Dikkat ederseniz fonksiyon değil, operatör (işlem) diyoruz. Çünkü, bu işlem tek başına değil, Perl bir diğer işlemi, “bağdaştırma/bağlama işlemi” (binding operator) dediğimiz =~ işareti ile birlikte kullanılır ve bize doğru/yanlış sonucunu verir. Bağlama işareti, solunda değerin içinde sağındaki “modelin” bulunup bulunmadığını bildir. Burada sağdaki model m// ile belirtilir. Örnek yapalım, bu karmaşık ifade anlaşılır hale gelecektir:
if(“dostlar#neredesiniz” =~ m/#/)
{print “Aranan bulundu\n” } else {print “Aranan bulunamadı\n” }
Ekrana “Aranan bulundu” yazdıracaktır. (“dostlar#reredesiniz” String’i yerine isterseniz bir değişken adı da koyabilirsiniz; arama değişkenin içerdiği değerde yapılır.) Buradaki “if” doğru/yanlış sonucu veren bir operatör doğru sonuç verdiği zaman birinci işlemi, yanlış sonuç verdiği zaman ikinci işlemi yapacaktır. Arama sonucu arananın benzeri bulunamazsa, sonucun yanlış değil doğru olması için bağlama operatörünü !~ olarak yazabiliriz. Örnek:
if(“dostlar#neredesiniz” !~ m/#/)
{print “Aranan bulunamadı\n” } else {print “Aranan bulundu\n” }
Metinlerinizde, Perl için özen anlamı olan şu karakterleri aratmak istiyorsanız, iki bölü işaretinin arasına bu karakteri yazarken önüne ters-bölü işareti koymanız gerekir:
^ $ + * ? . | ( ) { } [ ] \ /
Bir metinde iki karakterden biri veya diğerini aratacağınız zaman veya anlamına gelen dik çizgi (|) işaretini kullanmanız gerekir. örneğin, Perl aranan metinde “h” veya “H” harfini arasın istiyorsak, bunu şöyle yazabiliriz:
if($aranan_metin =~ m/(h|)/)..
m// operatörü ile joker karakterler de kullanabilirsiniz:
if($aranan_metin =~ m/T.K/)..
Perl, TEK, TAK, TÜK kelimelerini bulacak fakat mesela TANK kelimesini bulmayacaktır; çünkü bir adet nokta işareti ile verdiğiniz iki karakterin arasında sadece bir adet karakter bulunmasına izin verdiniz. Perl’de aranan modeli belirtmek için bir çok başka yöntem vardır. Örneğin verdiğiniz modelin bulunmasını değil, bulunmamasını istiyorsanız, önüne ^ işareti koyabilirsiniz. Bir başka örnek, bütün bir sınıfı belirtmek amacıyla aranan modeli köşeli parantez içine almak veya dizileri, 0-9, A-Z, a-z gibi kesme işaretiyle belirtmek olabilir. Fakat bunların çoğunun kısayolu da vardır:
Kısayol      Açık şekli      Anlamı
\d      [0-9]   Herhangi bir rakam
\w      [a-zA-Z_0--]   Herhangi bir alfanümerik karakter
\s      [\t\n\r\f]   Herhangi bir yazılmaz karakter
\D      [^0-9]   Rakam olmayan bir karakter
\W      [^a-zA-Z_0--]   Alfanümerik olmayan bir karakter
\S      [^\t\n\r\f]   Yazılmaz olmayan bir karakter
Bu kısayolların kullanımına bir örnek verirsek:
if($aranan_metin =~ m/\d/)..
deyimi ile metinde herhangi bir rakam bulunup bulunmadığını aratabilirsiniz. Kısayollar ve normal ifadeler birlikte kullanılarak, Perl’ün arama yeteneği genişletilebilir.
Bazen arattığımız karakter(ler)in metindeki yeri bizim için önem taşıyabilir. ^ işareti vereceğimiz karakterlerin aranan metnin başında, $ işareti de sonunda olmasına dikkat edilmesini sağlar. Örnek, aradığımız metni “Mus” harfleriyle başlamasını istiyorsak:
if($aranan_metin =~ m/^Mus)..
Aranan metnin “afa” ile bitmesini istiyorsak:
if($aranan_metin =~ m/afa$)..
Bu noktada eğer temizlemediyseniz, bir dosyadan okuttuğunuz metnin sonunda yeni satır karakteri bulunabileceğini hesaba katmalısınız. Perl’ün aranan karakterin kaç adet olması gerektiğini belirleyebilmemizi sağlayan kısayollar vardır:
Kısayol      Anlamı
+      En az 1 kere veya daha fazla
*      En az 0 kere veya daha fazla
?      0 veya 1 kere
{x}      Kesinlikle x kere
{x,}      En az x kere
{x,y}      En az x, en çok y kere
Bu kısayollar da diğer normal ifadeler ve kısa yollarla birlikte kullanılabilir. Örneğin, “H ile başlayan ve I ile biten ve arasında bir veya daha fazla herhangi bir karakter bulunan metinleri bul!” demek istiyorsanız, şu deyimi yazmalısınız:
if($aranan_metin =~ m/H.+I)..
Bu deyimle, HAKKI ve HALI bulunur, fakat HI bulunamaz.
Aradığımızı bulduk, diyelim. Elde ettiğimiz sonuç aranan bulunursa doğru (True), bulunamazsa yanlış (False) değerinden başka bir şey değil. Peki, içinde aradığımız değer bulunan String’i veya sayıyı öğrenemez miyiz? Öğreniriz. Perl bulduklarını sırayla $1, $2, $2 adlı değişkenlere yazar. Örnek:
$Metin1 = “HAKKI”;
if($Metin1 =~ m/(H.)K(.I)/)
{print “Bulundu\n” } else {print “Bulunmadı\n” }
print “$1\n$2\n”;
Prel’ün aradığı metnin büyük-harf veya küçük-harf olmasına aldırış etmemesini istiyorsak, m// işleminden sonra i (ignore) harfini koyarız. Arattığımızı arama yapılan metinde bütün geçtiği yerlerde bulmasını istiyorsak, yani arama yapılan metnin tümünün aranmasını arzu ediyorsak, m// operatöründen sonra g (global) harfini koyarız.
Peki, aradığımızın sadece bulunup bulunmadığını ve ne bulunduğunu öğrenmek istemiyoruz; fakat aradığımız şeyi değiştirmenizi istiyorsak! Bunu s/// işlemine (substitute, yerine koy) ile yaparız. Çalışma ilkesi tamamen m// işlemkine benzeyen s///, ikinci ve üçüncü bölü işaretleri arasına koyacağımız şeyleri, bulduklarının yerine koyar.
Sözgelimi elimizdeki metinde geçen bütün + işaretlerini boşluk (aralık) ile değiştirmek istiyoruz:
$Bosluklu_degisken = ($Artili_degisken =~s/\+/ /);
s/// işleminin de işleyişini değiştiren bir çok eki vardır. Bundan e (evaluate, değerlendir), eğer bulunan unsurun yerine konulan unsur bir hesap veya bir değişken içeriyorsa, bu değerlendirmenin yapılmasını sağlar.
$yeni_degisken =~ s/\d+/$1 + 1/e;
Perl, bu deyimle, bulduğu unsur diyelim ki 135 ise, anında 136 yapar.
Her ne kadar kullanışlı olsa da, s/// işlemi sadece bir unsuru bir başka unsura çevirdiği için, bazen yetersiz kalabilir. Bize bütün değişkende, söz gelimi bütün büyük harfleri küçük harf yapacak, bir işlemci gerekebilir. Bu işlemci, tr/// operatörüdür. Ve işte arzu ettiğimiz büyük harf-küçük harf değişlikliğini yapma deyimi:
$yeni_degisken =~ tr/A-Z/a-z/;
Bu işlemin işleyiş tarzını ve sonuçlarını, üç şekilde değiştirebiliriz:
c: seçilmeyenleri değiştir:
$yeni_degisken =~ tr/0-9/ /c;
Bu deyim, rakam olmayan herşeyin yerine boşluk koyar.
d: değiştirme, sil:
$yeni_degisken =~ tr/0-9//cd;
Bu deyim, rakam olmayan herşeyi siler.
s: tekrar edenleri teke düşür:
$yeni_degisken =~ tr/,/,/s;
Bu deyim, yanyana birden fazla virgülü tek virgül haline getirir.

Logged
 
TRForumcu.NeT | Bilgi ve Paylaşım Platformu
Gondolin
Bölüm Sorumlusu
*


Mesaj : 1.169
Forum Para : 7896.00 YTL
« Yanıtla #10 : 02 Mayıs 2008, 11:08:24 »

Form’dan gelen bilgilerde arama-bulma-değiştirme
Perl’de arama-bulma-değiştirme işlemlerini gözden geçirmeyi de tamamladıktan sonra, bir Form’dan gelen veriyi istediğimiz biçimde kullanılır hale getirmek için herşeyi öğrenmiş olduk. Şimdi forn_analiz.pl’i açın ve form_islem.pl adıyla kaydedin; ve programın baş tarafındaki şu deyimlere bakın:
................
   @girdiler = split(/&/, $ENV{'QUERY_STRING'});
................
   @girdi = split(/&/, $depo);
................
   ($anahtar, $deger) = split (/=/, $girdi);
   $anahtar =~ tr/+/ /;
   $deger =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
   $deger =~ tr/+/ /;
   $deger =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
   $deger =~s/<!--(.|\n)*-->//g;
................
   
Bu programı yazdığımızda içinde anlamadığımız şeyler bulunduğunu belirtmiştik; şimdi anlaşılmayan bir taraf kalmamış olsa gerek. Browser’ın yumak yapıp yolladığı Form bilgilerini içine yazdığımız $depo adlı değişkenin değerini & işaretinden bölümlere ayırdığımızı, ortaya çıkan bütün parçaları, @girdi dizisinin elemanları haline getirdiğimi ve sonra bu dizinin her bir satırını bu kez eşittir işaretinden bölüp, ortaya çıkan Stringleri bu kez %formveri adlı Bağlantılı Dizi (Hash) değişkenin anahtar/veri çiftleri olarak kaydettiğimi görüyorsunuz.
Şimdi bu işlemin arasında, hem anahtar adı olacak String’de, hem de değer olacak String’de önce + işaretlerini boşlukla değiştirdiğimizi; sonra biraz karışıkça bir deyimle, s/// işlemi yaptırdığımızı görüyorsunuz:
=~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
Aslında bu s/// işleminin arama bölümünü biliyoruz: “değeri a-f veya A-F ve 0-9 arasında olan iki basamaklı ve % ile başlayan herşeyi bul.” Fakat bulunan şeyin yerine konacak değer yabancı. Perl’ün paket denilen haricî araçlar dosyaları (externel utilities files) vardır. Bu paketler (modüller) Perl ile birlikte kurulur ve Perl programlarınızı çalıştıran Perl Programı tarafından tanınır. Burada gönderme yaptığımız “C” paketi 16 tabanlı sayı sistemiyle yazılmış kodların ASCII, ANSI ve Unicode karşılıklarını verir.
Yukarıdaki örnekte yer alan son s/// işlemi Web Form verisi yoluyla sitenize zararlı program kodu yollamak isteyebileceklere karşı alınmış bir önlemdir. Kötüniyetli kişi HTTP Server’a zararlı programları “<!---“ ve “-” işaretleri arasında yollamak zorundadır. Bu işlemle bu tür girdileri tümüyle yok ediyoruz.
Bu örnekte gördüğünüz tr/// ve s/// işlemlerini içeren deyimler, neredeyse bütün dünyada standart olarak kullanılır. Form işleme programında da bu bölümü aynen bırakacağız.
Yapacağımız ilk değişiklik, ekrana gönderdiğimiz değişiklikleri bu kez bir dosyaya göndermek olacağı için Perl programına geçmeden önce bu dosya ile ilgili hazırlıklar yapalım. Bu dosyada, ziyaretçilerimizden gelen bütün Form bilgileri belirli bir biçimde yazılması gerekir, ki sonra bu dosyayı Web Sitemize evsahipliği yapan bilgiyardan kendi bilgisayarımıza çekerek, inceleyebilelim, ziyaretçilerimiz hakkında fikir edinelim. Bu dosyadaki bilgilerin, Form’daki Input alanlarını sütun olarak düşünerek kaydedilmesi uygun olur. Bunun için önce içine Form bilgilerinin ekleneceği düzyazı dosyasını oluşturabiliriz, birinci satır olarak sütun başlıklarını yazabiliriz. Örneğin şöyle:
Adı   Adres   Kod   Merak   e-posta    mesaj      eğitim
Burada sütun başlıklarından sonraki ok işaretleri kelimelerin arasına sekme (Tab) koyduğumuzu gösteriyor. Form bilgilerimizi de değişken değerlerinin arasına sekme koyarak yazacağız. Şimdi bu dosyayı form_bilgileri.txt adıyla kaydedin. İsterseniz bu dosyayı daha sonra düzyazı programıyla değil bir veritabanı programı ile açabilirsiniz; sekme ile ayrılan metinler sütun haline dönüştürülür. (Bu alıştırmayı birlikte yapıyorsak, “eğitim” kelimesinden sonra Enter tuşuna basarak yeni satır (newline) kodu girmeyi unutmayın!)
Eğer hala yapmadıysanız, şimdi form_analiz.pl dosyasını düz yazı programınızda açın ve form_islem.pl adıyla kaydedin. Bu programın yaptığı iki iş var: (1) Form’dan gelen bilgileri %formveri değişkenine, Input alan adları anahtar, ziyaretçinin bu alana yazdıkları değer olarak şekilde yerleştirmek; sonra bir dizi print() fonksiyonu ile bunları ekranda görüntülemek. Yukarıda görmüştük ki, ekrana “yazdırmak” ile dosyaya “yazdırmak” arasında sadece bir dosya tutamağı farkı vardı. Hatırlarsak, dosya tutamağı (handle) dediğimiz şey, dosyayı açtığımız sırada verdiğimiz keyfî bir kelimeden ibaretti.
Demek ki önce Perl’e, biraz önce oluşturduğumuz ve Web sitemizde form_isleme.pl programının bulunduğu dizine gönderdiğimiz dosyayı ek yapılmak üzere açalım. (Şimdilik bu dosyayı kişisel Web Server’da Perl program dosyalarınızın durduğu dizine kopyalamakla yetineceğiz; fakat gerçek CGI yönetimi ile ilgili bilgileri ve bu dosyayı FTP ile HTTP Server’ına göndermeyi bundan sonraki bölümde ele alacağız.)
open (EKLE, “>>form_bilgileri.txt”);
Bu deyimle, biraz önce oluşturduğumuz ve tek satırlık sütun başlıklarımızı eklediğimiz metin dosyasını ek yapmak amacıyla açıyoruz; ve bu dosyaya EKLE tutamağını (Handle) veriyoruz.
Şimdi artık, Form’dan gelen bilgileri (%formveri değişke