Thread overview
Kelime döngüsünün oluşturulması
Dec 05, 2011
zafer
Dec 06, 2011
zafer
Dec 07, 2011
zafer
Dec 12, 2011
zafer
December 06, 2011

Merhaba,

KelimeMatik projesinin egzersiz kısmını hazırlıyorum. Buradaki durum şu şekilde çalışıyor. Giriş yapan kullanıcı egzersiz hazırla ekranına geçtikten sonra "Egzersiz Başlat" dügmesine basarak yeni bir egzersiz başlatıyor. Bu esnada biz arkaplanda egzersiz sınıfı üzerinden kullanılacak kelime listesini alıp global olarak tanımlanan "'kelimeListesi'" dizisine aktarıyoruz. sonra "'kelimeNo'" isimli değişkenimizi sıfırlayıp kelimeListesi dizisindeki ilk elemanı alıp ekrana basıyoruz. Tüm bu işlemler "Egzersiz Başlat" dügmesine bastıgımız zaman olup bitecek.

Ardından kullanıcı cevabı yazıp "Cevapla" düğmesine bastıgında cevabı kontrol ediyor, ardından "'kelimeNo'" değerini bir arttırıp "'kelimeListesi'" dizisinden sonraki kelimeli alıp ekrana basıyoruz. Hızlıca böyle birşeyler düşündüm ama sanki daha iyi çözümler olabilir gibi geliyor. Bu çözümden pek emin değilim, bu konuda fikri olan var mı?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 06, 2011

Doğru geliyor. Yalnızca globalde kuşkuluyum. Verilerin global olmaları engellenebilir mi?

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 06, 2011

Aslında engellenebilir ama bu sefer iki defa liste almak gerekiyor.

Yani şöyle, kullanıcı "Egzersiz Başlat" düğmesine tıklayınca soru listesini alıp ilk soruyu ekrana basıyoruz. Daha sonra cevabı yazınca bu sefer "Cavapla" düğmesine basıyor haliyle burada listeyi yeniden ele alıp bir sonraki soruyu bulup ekrana basmak gerekiyor. Bende iki defa liste almamak için "Egzersiz Başlat" düğmesine basılınca global kelimeListesini dolduruyorum ve ilk soruyu ekrana basıyorum ardından her "Cevapla" düğmesine basılınca listede bir sonraki soruya ilerliyorum.

Yani globalden vazgeçersek iki defa liste almak zorunda kalırız iki defa xml dosyası okumak demek bu da. Bilemiyorum durum ortada sen ne dersin?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 06, 2011

İkna olmadım. Belki de gtk'nin ayrıntılarını bilmediğim için böyle düşünüyorum ama iki farklı düğmenin işlenmesi sırasında aynı veriler kullanılamıyor mu?

Liste bir kere hazırlandıktan sonra önce Egzersiz Başlat tarafından sonra da Cevapla tarafından kullanılsa?

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 06, 2011

Bir yolunu buldum: addOnClicked() delegate aldığı için kolay. Aşağıdaki delegate düğmeye her basıldığında yerel bir değişkenin değerini arttırıyor ve çıkışa yazdırıyor:

import std.stdio
/* ... */
               int yerelDeğer;
               btnYeniKullaniciEkle.addOnClicked(
                   (Button) {
                       ++yerelDeğer;
                       writeln(yerelDeğer);
                   });

Yerel değişken yerine herhangi başka değişken de kullanılabilir. Eminim başka yöntemler de bulunabilir.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 07, 2011

Evet oldu :). Ali sen harikasın biraz farklı bir kodlama oldu ama çalıştı ve kelimeListesi ve kelimeNo değişkenleri artık yerel oldular.

Kodlar şöyle oldu.

private void EgzersizBaslat_Click(Button btn)
	{
		int kelimeNo = 0;

		Egzersiz calisma = new Egzersiz("/home/zafer/DProjeler/KelimeMatik/data/en-tr.xml");

		Kelime[] kelimeListesi = calisma.VerEgzersizSoruListesi();

		lblSoru.setMarkup("<span foreground='black' font='20' font_weight='bold'>" ~ kelimeListesi[kelimeNo].soru ~ "</span>");

		btnEgzersizBaslat.setSensitive(false);

		btnCevap.addOnClicked((Button)
		{
			++kelimeNo;
			if (kelimeNo < kelimeListesi.length)
			{
				lblSoru.setMarkup("<span foreground='black' font='20' font_weight='bold'>" ~ kelimeListesi[kelimeNo].soru ~ "</span>");
			}
			else
			{
				btnEgzersizBaslat.setSensitive(true);
			}
		});
	}

Buradaki bir durum EgzersizBaslat_Click metodu çalışmadan bizim buton çalışmıyor ama bunun şimdilk bizim için bir sorun olduğunu düşünmüyorum. Başka ne fikirlerin var Ali denemek için sabırsızlanmaya başladım. Birde buradaki temsilci (delegate) olayı daha geniş bir şekilde anlatırmısın. Bu işlmleri bu şekilde kullanmamıza olanak sağlayan nedir?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 09, 2011

Alıntı (zafer):

>

Birde buradaki temsilci (delegate) olayı daha geniş bir şekilde anlatırmısın. Bu işlmleri bu şekilde kullanmamıza olanak sağlayan nedir?

Bu konu işlevlerden başlayarak uzun uzun anlatılabilir. İsimsiz işlevlerin yararına değinilir, onların davranışlarının değiştirilebilmelerinin parametrelerle nasıl yapılabildiği gösterilir ve temsilcilere gelinebilir. Şu sıralarada zaman bulamıyorum. :)

Temsilci yerine başka ne kullanılabileceğini gösterebilirim. Ama önce belgeleri okurken yeniden hatırladığım bir bilgiyi vereceğim. Hani üye işlevler belirli bir nesne üzerinde işlerler ya... Yani aslında üye işlevin bir de gizli bir 'this' göstergesi olur ve üye işlev o göstergenin gösterdiği nesne üzerinde işler.

İşte temsilciler de aynı sistemi kullanıyorlar. Hatta perde arkasında aynı üye işlev gibi gerçekleştiriliyorlar. Temsilciler bir sınıf (veya yapı) türü olmadıklarından onlar üye işlev değiller ve üzerlerinde işledikleri nesne yok. Derleyicinin bu durumun üstesinden gelmek için yaptığı şu: temsilcinin oluşturulduğu ortamdaki bütün değişkenleri sanki bir nesnenin üyeleriymiş gibi saklıyor. O ortamı gösteren gösterge 'this' yerine geçiyor. (Daha teknik olarak, temsilcinin oluşturulduğu 'stack frame'i gösteren bir gösterge saklıyor.)

Temsilcinin işlevi de o 'this' göstergesi ile işleyen bir üye işlev gibi kullanılıyor.

Sonuç olarak bizim için canlı tutulmuş olan yerel değişkenler üzerinde işleyen isimsiz bir işlev ediniyoruz. O isimsiz işlev (yani 'delegate') ilerideki bir zamanda işletilirken bu ortamı kullanabiliyor.

Bütün bunlardan da anlaşılacağı gibi, "yerel değişkenler"+"temsilci" kullanmak yerine başlı başına bir tür ve onun üye değişkenlerini de kullanabiliriz. (Zaten temsilcileri bulunmayan C++98 gibi dillerde de öyle yapılmak zorundadır.)

Bunun örneğini sonra göstereceğim. Hatırlarsam... :)

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 11, 2011

Alıntı (acehreli:1323461554):

>

Hani üye işlevler belirli bir nesne üzerinde işlerler ya... Yani aslında üye işlevin bir de gizli bir 'this' göstergesi olur ve üye işlev o göstergenin gösterdiği nesne üzerinde işler.

O söylediğim, C++ programcılarına çok yakın bir kavramdır. D'de de üye işlevler içinde 'this' diye bir kavram var. (Hem yapılarda hem sınıflarda.) O da aynen C++'ta olduğu gibi "şu anda üzerinde işlemekte olduğumuz nesne" anlamına geliyor. Bunu zaten D'nin kurucu işlevlerinde de görürüz:

import std.stdio;

class Sınıf
{
   int i;

   this(int i)
   {
       this.i = i;
   }

   void bilgi()
   {
       writefln("bilgi() %s adresindeki nesne üzerinde çağrıldı", &this);
       writefln("Bu nesnenin i üyesinin değeri şu: %s", this.i);
   }
}

void main()
{
   auto nesne = new Sınıf(42);
   nesne.bilgi();
}

Bir çıktısı:

'bilgi() 7FFF33D8CF28 adresindeki nesne üzerinde çağrıldı
Bu nesnenin i üyesinin değeri şu: 42
'

Yukarıda hem kurucu içinde hem de bilgi() içinde this kullanılıyor. İşte, nesnenin üyelerinin ve nesnenin üzerindeki işlemin bir araya gelerek çağrılması olayı D'de temsilcilerin gerçekleştirilmesinin aynısıymış.

Alıntı:

>

Bunun örneğini sonra göstereceğim. Hatırlarsam... :)

Hatırladım! :-p Button ve addOnClicked() ile temsilci kullanımını basit bir örnekle göstereceğim. Yukarıda söylediğimin örneği olarak '&işlemciNesne.özelİşlem' kullanımına bakın:

import std.stdio;

/* Button gibi kullanılan bir sınıf */
class Düğme
{
   /* Koda açıklık getirmek için tanımlanmış bir takma isim */
   alias string delegate(Düğme) İşlemci;

   /* Her Düğme nesnesinin işlemcileri var. Düğmeye basıldığında teker teker
    * bunlar işletilecekler. */
   İşlemci[] işlemler;

   /* addOnClicked()'in benzeri olan bir işlev. Tek yaptığı, kendisine
    * verilen işlemi basitçe işlemciler dizisine ekliyor. Daha sonradan
    * düğmeye basıldığında işletecek. */
   void ekle(İşlemci işlem)
   {
       işlemler ~= işlem;
   }

   /* Düğmeye basılmış. Bütün işlemleri teker teker işletiyor. Bu basit
    * örnekte yalnızca onların sonuçlarını bir diziye yerleştirip diziyi
    * yazdırıyoruz. */
   void bas()
   {
       string[] sonuç;

       foreach (işlem; işlemler) {
           sonuç ~= işlem(this);
       }

       writeln(sonuç);
   }
}

/* Burada asıl göstermek istediğim bu: Kendisi bir temsilci olmasa da, üye
* işlev temsilci gibi kullanılmaya uygun: Düğme alıyor ve string
* döndürüyor. Uygun. */
class İşlemciSınıf
{
   string özelİşlem(Düğme düğme)
   {
       return "selam";
   }
}

void main()
{
   /* Daha sonradan basılacak olan bir düğme. */
   auto düğme = new Düğme;

   /* addOnClicked()'te olduğu gibi iki tane temsilci ekleyelim. */
   düğme.ekle(
       (Düğme) {
           return "merhaba";
       });

   /* Değişiklik olsun diye farklı bir düzende. */
   düğme.ekle((Düğme) { return "hello"; });

   /* Önemli olan yer burası. delegate türünde olmayan bir nesnenin üzerinde
    * çağrılan bir üye işlev, temsilci gibi kullanılıyor. Önemli: özelİşlem()
    * burada çağrılmıyor. O daha sonra bas() içindeyken tam da bu nesne
    * üzerinde işletilecek. */
   auto işlemciNesne = new İşlemciSınıf;
   düğme.ekle(&işlemciNesne.özelİşlem);

   /* ... arada başka işlemler olabilir ... */

   /* Kullanıcı sonunda düğmeye basıyor ve pencere sistemi bizim düğmenin
    * bas() işlevini çağırıyor. */
   düğme.bas();
}

Sonuçta iki temsilci ve tek "nesne"+"üye işlev" çağrıları şu çıktıyı üretiyorlar:

'["merhaba", "hello", "selam"]
'

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 12, 2011

Ali güzel ve detaylı açıklama için çok teşekkürler. Hepsini tam olarak anladım desem doğru olmaz ama kesinlikle ufkumu çok genişletti ve özellikle arka planda dönen olguları farketmemi sağladı. Eline sağlık diyorum.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]