Eggdrop İçin Tcl Değişkenler, Listeler ve Diziler Rehberi
İçindekiler
Bir Eggdrop scripti yazarken er ya da geç veri saklamanız gerekir: Kullanıcıların puanları, bir kanalın son konusu, banlanmış kelimeler listesi, kimin en son ne zaman komut kullandığı... Bu verileri yönetmenin yolu Tcl'in değişkenleri, listeleri ve dizileridir. Bu rehberde Tcl değişkenler ve veri yapılarını Eggdrop scriptleri bağlamında anlatıyoruz.
Değişkenler: set ve $
Tcl'de değişken tanımlamak için set kullanılır, değerini okumak için başına $ konur:
set selam "Merhaba"
set sayi 42
putlog "$selam, sayi: $sayi"
Tcl'de her şey aslında bir metindir. 42 bir sayı gibi davranabilir ama içte metin olarak tutulur. Sayısal işlemler için expr kullanılır:
set toplam [expr {$sayi + 8}]
incr sayi
incr sayi 5
incr, bir sayıyı artırmanın kısa yoludur. expr içindeki ifadeyi süslü parantezle yazmak hem daha hızlıdır hem de güvenlik açısından önerilir.
Kapsam: global ve Prosedürler
Tcl'in yeni başlayanları en çok şaşırtan kuralı budur: Prosedürler kendi değişken alanına sahiptir. Dışarıda tanımlanan bir değişken prosedürün içinden doğrudan görülmez:
set kanal_mesaji "Hos geldiniz!"
proc karsila {nick uhost hand chan} {
global kanal_mesaji
puthelp "NOTICE $nick :$kanal_mesaji"
}
global satırı olmadan prosedür "can't read kanal_mesaji: no such variable" hatası verir. Eggdrop'un kendi değişkenleri de (örneğin botnick) prosedürlerde global botnick ile kullanılır. Bu hata, sık hatalar listemizin en üst sıralarındadır.
Listeler
Liste, sıralı elemanlardan oluşan bir veri yapısıdır. Eggdrop'ta kanal listeleri, kullanıcı listeleri ve kelime listeleri genellikle liste olarak tutulur.
set yasakli [list reklam spam bedava]
lappend yasakli kripto
llength $yasakli
lindex $yasakli 0
lsearch -nocase $yasakli "SPAM"
lsort $yasakli
| Komut | Ne yapar? |
|---|---|
list | Yeni bir liste oluşturur |
lappend | Listeye eleman ekler |
llength | Eleman sayısını verir |
lindex | Belirli sıradaki elemanı verir (0'dan başlar) |
lsearch | Elemanı arar, sırasını verir; yoksa -1 |
lsort | Listeyi sıralar |
lrange | Listenin bir bölümünü verir |
lreplace | Eleman değiştirir veya siler |
Kullanıcı Metnini Listeye Çevirmek: split ve join
Kanaldan gelen metin ham bir metindir. Kelimelere ayırmak için split kullanın:
set kelimeler [split $text]
set ilk [lindex $kelimeler 0]
set geri_kalan [join [lrange $kelimeler 1 end]]
split metni boşluklardan bölerek güvenli bir listeye çevirir. join ise listeyi tekrar metne dönüştürür. Ham kullanıcı metnini split olmadan doğrudan lindex gibi liste komutlarına vermek, metin içindeki süslü parantez veya tırnak gibi karakterler nedeniyle hatalara, hatta güvenlik sorunlarına yol açabilir.
Örnek: Mesajda yasaklı kelime var mı?
proc yasak_kontrol {nick uhost hand chan text} {
global yasakli
foreach kelime [split [string tolower $text]] {
if {[lsearch -exact $yasakli $kelime] != -1} {
putkick $chan $nick "Yasakli kelime"
return
}
}
}
Diziler (Array)
Dizi, anahtar-değer çiftlerinden oluşur. Her kullanıcı için ayrı bir değer saklamak gerektiğinde idealdir:
set puan(Ayse) 10
set puan(Burak) 7
incr puan(Ayse)
putlog "Ayse'nin puani: $puan(Ayse)"
Dizilerle çalışmak için yararlı komutlar:
info exists puan(Deniz)
array names puan
array size puan
unset puan(Burak)
info exists kontrolü önemlidir: Var olmayan bir dizi elemanını okumaya çalışmak hata verir. Bir kullanıcının puanını artırmadan önce kaydı olup olmadığını kontrol edin:
if {![info exists puan($nick)]} { set puan($nick) 0 }
incr puan($nick)
Nickler büyük-küçük harf farkı içerebileceği için anahtar olarak kullanmadan önce string tolower ile küçük harfe çevirmek tutarlılık sağlar.
Sözlükler (dict)
Güncel Tcl sürümleri, dizilere benzeyen ama bir değer gibi taşınabilen dict yapısını sunar:
set kullanici [dict create nick Ayse puan 10 seviye 2]
dict get $kullanici puan
dict set kullanici puan 11
Dict'ler, bir veri kümesini prosedürler arasında parametre olarak aktarmak veya dosyaya yazmak için kullanışlıdır.
Verileri Kalıcı Hâle Getirmek
Değişkenler bellekte tutulur; bot yeniden başladığında kaybolur. Puanlar veya istatistikler gibi kalıcı olması gereken verileri bir dosyaya yazmalısınız:
proc puan_kaydet {} {
global puan
set f [open "puanlar.txt" w]
puts $f [array get puan]
close $f
}
proc puan_yukle {} {
global puan
if {![file exists "puanlar.txt"]} { return }
set f [open "puanlar.txt" r]
array set puan [read $f]
close $f
}
array get diziyi bir listeye, array set ise listeyi tekrar diziye dönüştürür. Kaydetme işlemini düzenli aralıklarla yapmak için timer ve utimer yazımızdaki zamanlayıcıları kullanabilirsiniz.
Gerçek Bir Senaryo: Kanal Aktivite Sayacı
Kanaldaki her kullanıcının kaç mesaj yazdığını sayan basit bir script düşünelim. Her mesajda pubm bind'i tetiklenir, kullanıcının küçük harfe çevrilmiş nicki anahtar olarak kullanılarak bir dizideki sayaç artırılır. Bir !enaktif komutu ise diziyi listeye çevirir, sayıya göre sıralar ve ilk beş kişiyi kanala yazar. Bot yeniden başlatıldığında verilerin kaybolmaması için her on dakikada bir dizi dosyaya kaydedilir, bot açılırken de dosyadan yüklenir. Bu küçük senaryo; değişkenleri, dizileri, listeleri, sıralamayı ve dosya işlemlerini bir arada kullandığı için Tcl öğrenmek isteyenler için harika bir alıştırmadır.
Metin İşleme Komutları
Değişkenlerle birlikte en çok kullanacağınız komut ailesi string komutlarıdır. Kullanıcı mesajlarını işlerken neredeyse her scriptte karşınıza çıkarlar:
| Komut | Ne yapar? |
|---|---|
string tolower | Metni küçük harfe çevirir |
string toupper | Metni büyük harfe çevirir |
string length | Karakter sayısını verir |
string match | Joker karakterli eşleştirme yapar |
string first | Bir alt metnin ilk geçtiği yeri bulur |
string range | Metnin bir bölümünü keser |
string trim | Baştaki ve sondaki boşlukları siler |
string map | Metindeki parçaları başka parçalarla değiştirir |
Eggdrop ayrıca IRC'ye özgü bazı yardımcılar sunar. Örneğin nickleri karşılaştırırken IRC'nin büyük-küçük harf kurallarını dikkate alan karşılaştırma komutları ve kontrol karakterlerini (renk, kalın yazı gibi) metinden temizleyen fonksiyonlar bulunur. Kullandığınız sürümün belgesinde bu yardımcıları incelemeniz, tekerleği yeniden icat etmenizi önler.
Sık Yapılan Hatalar
Tcl ile yeni tanışanların en sık düştüğü tuzakları bir arada toplayalım. Birincisi, prosedür içinde global satırını unutmaktır; bu durumda dışarıdaki değişken yerine yeni ve boş bir yerel değişkenle çalışırsınız ve değişiklikler kaybolur. İkincisi, liste ile metni karıştırmaktır; ham kullanıcı metnini liste komutlarına vermek tırnak ve parantez içeren mesajlarda hataya yol açar. Üçüncüsü, var olmayan dizi elemanını okumaya çalışmaktır; her zaman önce info exists ile kontrol edin. Dördüncüsü, büyük-küçük harf tutarsızlığıdır; aynı kişinin nicki bir kez büyük, bir kez küçük harfle yazıldığında dizide iki ayrı kayıt oluşur. Beşincisi ise değişkenleri gereğinden fazla global yapmaktır; yalnızca gerçekten paylaşılması gereken verileri global tutun, geri kalanını prosedür içinde yerel bırakın.
Ad Alanları (namespace)
Script sayınız arttıkça değişken ve prosedür isimlerinin çakışma ihtimali yükselir. Tcl'in namespace özelliği, scriptinizin bütün değişkenlerini ve prosedürlerini kendine ait bir alana yerleştirmenizi sağlar. Böylece iki farklı script aynı isimde bir değişken kullansa bile birbirini etkilemez. Küçük scriptlerde basit bir önek yeterli olur, ancak büyük ve paylaşılacak scriptlerde namespace kullanmak profesyonel bir alışkanlıktır.
Sonuç
Değişkenler, listeler ve diziler Eggdrop scriptlerinin hafızasıdır. global kuralını unutmayın, kullanıcı metnini her zaman split ile işleyin, dizi elemanlarına erişmeden önce varlığını kontrol edin ve kalıcı verileri dosyaya kaydedin. Zamana bağlı işler için sıradaki rehberimiz timer ve utimer.
IRC sorunun mu var? Kanalda birlikte çözelim.
💬 Kanala BağlanSıkça Sorulan Sorular
Prosedür içinde dışarıdaki değişkene neden erişemiyorum?
Tcl'de prosedürlerin kendi değişken alanı vardır. Dışarıdaki bir değişkeni kullanmak için prosedürün başında global komutuyla bildirmeniz gerekir.
Liste ile dizi arasındaki fark nedir?
Liste sıralı elemanlardan oluşur ve sırayla erişilir. Dizi (array) ise anahtar-değer çiftlerinden oluşur ve anahtarla erişilir.
Kullanıcıdan gelen metni neden split ile bölmeliyim?
Ham metin özel karakterler içerebilir ve liste komutlarında beklenmedik sonuçlar doğurabilir. split, metni güvenli bir listeye dönüştürür.


