Perl Öğreniyoruz - 4

0
cayfer
Daha önceki bölümler:
1. bölüm
2. bölüm
3. bölüm
Bu hafta konumuzda çağrışımlı listeler var, Haftaya "regexp"ler! Bu arada merak ettiğim birşey var: Acaba bu Perl tefrikasından yararlanan var mı?

Çağrışımlı Listeler

C programcılarını biraz üzelim isterseniz! Listelerde (array) indekslerin sıfırdan başlayan ardışık tamsayılar olması gerektiğini düşünenler yanılıyor. Perl listelerinde indeks olarak alfabetik diziler hatta eksi sayılar kullanabilirsiniz. Tek yapmanız gereken indeksleri "[" ve "]" arasında değil "{" ve "}" arasında yazmanız ve listenin tümünden söz ederken %liste notasyonunu kullanmak olacaktır.

Örneğin, web sitenizin aylık ziyaretçi istatistiklerini çıkaran bir programın içinde

    $ziyaret{'Ocak'} = $ziyaret{'Ocak'} + 1;
gibi bir deyim kullanabilirsiniz. İndeksi "Ocak" olan liste elemanının değerini bir arttırmak için bundan daha kullanışlı nasıl bir yapı olabilirdi ki?

Çağrışımlı lisstelerin yararını ve kullanımını en kolay bir örnek problemle anlatabilirim:

Diyelim ki bir basit metin dosyasında her sözcüğün kaç kez geçtiğini saymanız gerekiyor. Örneğin "bir kere bir iki, bir kere iki iki eder" gibi bir satır içeren dosya üzerinde çalıştığında, programımız
bir - 3
kere - 2
iki - 3
eder - 1
gibi bir çıktı üretmelidir.

Bu işi yapan Perl kodu şöyle birşey olabilir:

      #!/usr/local/perl
      while ( $satir = <> ) {
         @sozcukler = split (/W/, $satir);
         foreach $sozcuk (@sozcukler) {
           $sayac{$sozcuk}++;
         }
      }
      foreach $sozcuk ( sort( keys(%sayac) ) ) {
          print "$sozcuk - $sayac{$sozcuk}
";
      }
      exit;
Şimdi bu programı satır satır bir gözden geçrirelim:

#!/usr/local/perl
Bu satırım amacını biliyor olmalısınız. Gene de hatırlatmakta yarar var: UNIX kabuk programına bu satırın ardındaki satırların /usr/local/ dizinindeki "perl" isimli program tarafından yorumlanması gerektiğini bildiriyor.

 while ( $satir = <> ) {
Hmmm.. bu satır biraz ilginç! "<>" dosyasından okuyabildiği sürece satır okuyacak ve her defasında okuduğu satırı "$satir" değişkenine atayacak. Bu kadarı belli de <> dosyası hangi dosya, nerede duruyor, neden bir "open" deyimiyle açılmadı?

Perl ile kod yazdığınızı unutuyorsunuz herhalde! Dosyayı açmadıysanız Perl sizin için açacaktır. Açılacak dosyanın adını kodun içinde belirtmediğinize göre, bunu programı çalıştırırken komut satırından vereceksiniz demektir. Güzel di mi? Evet, "elmas operatörü" (diamond operator) denen <> operatörü, Perl kodunu çalıştırırken komut satırında vereceğiniz dosyadan okumak için kullanılır.

@sozcukler = split (/W/, $satir);
Bir ilginç satır daha... Deneyimli programcılar hemen bu komutu okumayı başaracaktır: $satir değişkenindeki karakter dizisi "birşeylere göre" parçalanıp her bir parça @sozcukler listesine bir eleman olarak atanacak. İyi de bu "birşeyler" de ne? Henüz regexp'leri (regular expressions) anlatmadım. O yüzden bu "birşeyleri" "sozcük içinde yer alamayacak karakterler" olarak okuyunuz. Yani "/W/" --> "Sözcük içinde yar alamayacak karakterler".

Boşluklar, virgüller, diğer noktalama işaretleri, tab karakterleri vs hepsi sözcük içinde yer alamayacak karakterler olduğu için $satır karakter dizisi mükemmel bir şekilde sözcüklere parçalanacak ve her bir parça da @sozcukler listesine birer eleman olarak yerleştirilecektir. Satırın ilk sözcüğü $sozcukler[0]'a, ikinci sözcüğü $sozcukler[1]'in içine, vs.

Bu noktada Türkçe'ye özgü karakterlerin sorun çıkaracağını ve ne yazık ki "ğ", "ş" gibi karakterlerin "sözcük içinde yer alamayacak karakter" olarak değerlendirileceğini belirtmek isterim. Bunun sorumlusu kim biliyor musunuz? Türk Standartları Enstitüsü. Uzun yıllar önce karakter kümelerinin uluslararası standartlara oturtulması toplantılarına "yurt dışı seyahat sırası gelen" ama ingilizce bilmeyen ve bilgisayar bilimlerinden anlamayan bürokratların "gezsinler ve alışveriş yapsınlar diye" gönderilmesi nedeniyle tren kaçmıştı. 5-6 yıl sonra bir fırsat daha yakalamıştık, o toplantılara da ödenek olmadığı gerekçesiyle kimse gönderilmedi. İşte şimdi bu zavallı tavırların meyvelerini topluyoruz.

Neyse..

foreach $sozcuk (@sozcukler) {
@sozcukler listesinin herbir elemanını sırayla "$sozcuk" değişkenine alır ve döngüyü tekrarlar.
$sayac{$sozcuk}++;
%sayac çağrışımlı listesinin $sozcuk'üncü elamanını bir arttıtıyor! Örneğin $sozcuk değişkeninde "eder" varsa, %sayac listesinin "eder" indeksli elemanını bir arttıracaktır. Dİkkat ederseniz %sayac listesinin tek bir elemanından, yani "eder"inci elemanından söz ederken "$sayac" dedik (ilk karakteri "$"). Normal bir liste değil de çağrışımlı bir listeden söz ettiğimizi de indeksi "{" ve "}" karakterleri arasında yazarak belli ettik.

Bir numara daha çektik aslında bu satırda...
$sozcuk değişkenine ilk kez "bir" sözcüğü geldiğinde bir arttırmaya çalışacağımız $sayac{'bir'} henüz tanımsız. Tanımsız bir değeri bir arttırmak sorun çıkarmayacak mı? Hayır, çıkarmayacak! Unutmayın Perl kullanıyoruz. Herşey programcılar için! Madem programcı bir değerin bir arttırılmasını istiyor, Perl bunu yerine getirecektir. Eğer tanımsız bir değeri bir arttırmak istiyorsa önce o değeri tanımlı kılacak, sonra ilk değer olarak sıfır atayacak sonra da bir arttıracaktır.

foreach $sozcuk ( sort( keys(%sayac) ) ) {
Tüm satırlar okunduğuna ve tüm sözcüklerin kaçar kez tekrarlandığı da sayıldığına göre artık elde ettiğimiz sonuçları görüntüleyebiliriz.

Şimdi %sayac çağrışımlı listesi içinde dosyamızdaki sözcük çeşidi kadar eleman var. Elemanların indeksleri de sözcüklerin kendisi. Listenin herhangi bir indeksli elemanında da o sözcüğün kaç kez geçtiğinin sayısı var.

Bir başka deyişle

$sayac{'bir'}  --> 3
$sayac{'kere'} --> 2
$sayac{'iki'}  --> 3
$sayac{'eder'} --> 1
İndeksleri ardışık doğal tamsayılar olan bir listeyi dolaşmak kolay! İndeksin sıfırdan başladığı, bir sonrakinin de bir olduğu belli. Oysa çağrışımlı listelerde durum bu kodar kolay değil. İndeksler herhangi bir kümeye ait olmadıkları için akla gelen her değeri alabilirler. Dolu bir çağrışımlı listenin tüm elemanlarını dolaşmak istediğinizde keys( ) fonksiyonu kullanmalısınız. Bu fonksiyon parametresi olarak verilen çağrışımlı listenin tüm indeksklerini normal bir listeye doldurup geri gönderir.

Yani

@indeksler = keys(%sayac);
diye bir komut verirseniz, @indeksler listesi
$indeksler[0] = "bir",
$indeksler[1] = "kere",
$indeksler[2] = "iki",
$indeksler[3] = "eder"
şeklinde doldurulur. Bu anahtarlar listesinin hangi sırayla doldurulacağını önceden kestiremezsiniz. Tamamen anahtar (indeks) değerlerine bağlıdır. Bu listeye makul bir sırada erişmek isterseniz ayrıca "sort( )" fonksiyonuyla sıralayabilirsiniz.

keys( ) fonksiyonunun bir çağrışımlı listenin anahtarlarını toparlayıp vermesi gibi values( ) fonksiyonu da bir çağrışımlı listenin değerlerini derleyip geri gönderir.

Yukardaki örnek için

keys(%sayac)   --> ("bir", "iki", "kere", "eder);
values(%sayac) --> (3,     3,     2,      1)
listeleri alınabilir.

Çağrışımlı listelere eleman eklemek kolaydır. İndeksini ve listeye eklenmesi istediğiniz değeri

     $liste{'indeks'} = $deger; 
benzeri bir deyimle istediğiniz zaman ekleyebilirsiniz.

Eleman çıkarıp atmak içinse "delete($liste{'indeks'});" deyimini kullanmalısınız.

Görüşler

0
FZ
Hocam, öncelikle çağrışımlı listeler konusunu anlattığınız ve diziyi örneklerle zenginleştirdiğiniz için teşekkürler. C kurallarına alışık pek çok programcı için evet, çağrışımlı listeler epey garip ve fantastik ama göze güzel görünen yapılar ;-) Tabii mesela bu tip bir liste yapısının kullanılmasına izin veren dilleri geliştirenleri de ayrıca takdir etmek lazım, başlıbaşına bir iş!

Bir de acaba birileri bu yazı dizisinden faydalanıyor mu demişsiniz, hemen şuna dikkat çekmek isterim ki mesela regexp konusuna girdiğinizde, bundan sadece Perl programcıları değil, JavaScript, VBScript gibi regexp'in kullanıldığı programlama dillerinde sistem geliştirenler de faydalanacaktır.

Yani demem o ki pekçok kişi yazılarınızı takip ettikleri takdirde Perl ile program yazmaya kalkmasalar bile işlerine yarayacak fikirleri, bilgileri edinecekler, belki de birtakım kalıpların dışına çıkabilme becerisini kazanacak ya da en azından 'vay canına demek böyle de bir şey bu şekilde yapılabiliyormuş' diyecektir (bunu buraya yazarlar mı orası ayrı konu ;-)

Yazmaya ve paylaşmaya devam!
0
anonim
Valla şahsen benim bildiğim bir çok kişi, yaw ne güzel oldu şeklinde yaklaşıyor. FM okurlarında (genel IT sektörümüzde mi yoksa) bir miktar yazmaya karşı çekingenlikten olsa gerek, tepkiler genelde sözel veriliyor. O yüzden siz hiç dert etmeyin, çok güzel bir yazı dizisi oluşturdunuz elinize sağlık ve inanın takip edenleriniz var.
0
Anduril
Can Uğur AYFER hocam FM Forumlarında İlanlar kısmındaki sizle ilgili yazıyı okursanız sevinirim. Artık daha dikkatli davranırsınız kitaplarınızı yayınlarken. Kolay gelsin sağolun.
Görüş belirtmek için giriş yapın...

İlgili Yazılar

Perl programcısı olmaktan gurur duyanlar için özel !

sundance

Perl'ün yaratıcısı Larry Wall, alışageldiğimiz tarzında yaptığı sunumla, 7. geleneksel Perl Soğanının Durumu isimli toplantıda yine herkesi kırdı, geçirdi :)

'Biz, isteksizler,
cahiller tarafından öncülük edilen bir yolda,
imkansızı gerçekleştirmeye çalışıyoruz.
O kadar uzun süredir o kadar çok şeyi, (elimizdeki) o kadar az şeyle gerçekleştirdik ki
Artık (elimizdeki) hiçbir şeyle, herhangibir şeyi yapabilecek hale yetkinliğe eriştik.'

Kevin Poulsen iş başında!

sundance

Güvenlik dünyasının meşhur kötü çocuklarından, eski Security Focus yazarı Kevin Paulsen, yazdığı bir Perl scriptle U.S. National Sex Offender Registry kayıtları ile MySpace kullanıcılarını karşılaştırıp, bir cinsel suç zanlısının tespitine yardımcı olmuş.

Kendisini daha çok Los Angeles'daki KISS FM'in 102. arayan kişiye verdiği Porsche 944 S2'i kazanabilmek için, bütün telefon konuşmalarını durduran kişi olarak tanıdığımız Dark Dante kod adlı Poulsen yıllardır bilgi güvenliği alanında gazetecilik yapmakta, hatta zaman zaman bu olaydaki gibi otoritelere yardımcı olmakta.

Perl, Divx, altyazı ve başının çaresine bakabilmek üzerine

sundance

Uzun zamandır izlemek istediğim, The Hustler'ı seyretmek için sonunda zaman bulabildim. Paul Newman'ın 1962'de başrolünü oynadığı bu film, yıllar sonra Color of Money'e de konu olacak Fast Eddie Felson'ın hikayesini anlatıyordu. Dahası Unix Junkie makalemde bahsettiğim insan modelinin belki de en iyi örneklerinden biriydi.

Fakat küçük bir problem vardı, filmindeki hiçbir dialoğu kaçırmamak için altyazıya ihtiyaç duyuyordum, fakat benim elimdeki film iki cd olmasına rağmen bulabildiğim yegane ingilizce altyazı üç cdlikti.

Durumdan vazife çıkartmaya zaten hazır bir FM sakini olarak, sıvadım kolları ve küçük bir perl betiki yazdım bu işi yapması için. Film hatırladığımdan bile güzeldi, ama böyle bir durumda bir beş, on dakika içinde problemi çözebilmek daha bile keyifliydi, GNU/Linux kullanıyor olmak keyifliydi :)

Perl // Küçük Regexp El Kitabı

Ansugo

Çok fazla kod yazıyor, ama bazı yerlerde tıkandığınızı hissediyorsunuz; == ile karşılaştırma yapabiliyor, ama string içinde arama yapmakta istiyorsunuz; ve en güzeli herhangi bir stringin altindan cikip cikmak istiyorsunuz, o zaman buyurun düzenli ifade cumhuriyetine.

KSpyware

tongucyumruk

KSpyware adının çağrıştırdığının aksine KDE üzerinde çalışan bir casus yazılım veya casus yazılım tarayıcısı değil. KSpyware, Win32 platformunda çalışan özgür bir casus yazılım. Klasik anlamdaki casus yazılımlardan en önemli farkı kodlarının tamamen açık olması. Gilbert Nzeka adlı bir programcı tarafından Windows altında casus yazılımlar geliştirme yöntemlerini ortaya koymak amacıyla geliştirilen bu program bilin bakalım hangi programlama diliyle yazılmış?

Not: Bu programı GNU/Linux platformuna port edecek gönüllü bir arkadaş aranıyor.