Jump to page: 1 2
Thread overview
D.ershane opEquals eşitlik karşılaştırması
May 02, 2011
erdem
May 02, 2011
erdem
May 02, 2011
erdem
May 02, 2011
erdem
May 26, 2011
mert
May 26, 2011
mert
May 26, 2011
erdem
May 26, 2011
erdem
May 26, 2011
mert
May 02, 2011

Şans eseri TDLP'da da aynı konuyu okuyordum. Dershane'de aynı yerdeyim :)

import std.string, std.stdio;

class Saat {
   int saat;
   int dakika;
   int saniye;

   override bool opEquals(Object o) const {
       auto sağdaki = cast(const Saat) o;

       return((saat == sağdaki.saat)
              &&
              (dakika == sağdaki.dakika)
              &&
              (saniye == sağdaki.saniye));
   }


   override string toString() const {
       return format("%02s:%02s:%02s", saat, dakika, saniye);
   }

   this(int saat, int dakika, int saniye = 0) {
       this.saat   = saat;
       this.dakika = dakika;
       this.saniye = saniye;
   }
}

class ÇalarSaat : Saat {
   int alarmSaati;
   int alarmDakikası;

   override bool opEquals(Object o) const {
       auto sağdaki = cast(const ÇalarSaat)o;
       return((super == o)
              &&
              (alarmSaati == sağdaki.alarmSaati)
              &&
              (alarmDakikası == sağdaki.alarmDakikası));
   }

   override string toString() const {
       return format("%s ♫%02s:%02s", super.toString(),
                     alarmSaati, alarmDakikası);
   }

   this(int saat, int dakika, int saniye,
        int alarmSaati, int alarmDakikası) {
       super(saat, dakika, saniye);
       this.alarmSaati    = alarmSaati;
       this.alarmDakikası = alarmDakikası;
   }
}

void main() {
   auto değişken0 = new Saat(6, 7, 8);
   auto değişken1 = new ÇalarSaat(6, 7, 8, 1, 2);

   assert((değişken0 == değişken0)
          &&
          (değişken0 == değişken1)
          &&
          (değişken1 == değişken0));
}

Bu programı çalıştırdığımda 'segmentation fault' hatası veriyor.

'assert' kullanımını özellikle bu şekilde yazdım. Çünkü TDLP'de el sıkışma gibi bir kavramdan bahsediyordu. Yani 'x = y' ise 'y = x' olmalı hatta kendisiyle 'x = x' şeklinde bile karşılaştırmış. Hatta örneğin iki referans 'null' ise 'true' döndürüyor. Yani bir nesneye bağlanmamış referansla da karşılaştırma yapıyor.

Ama tüm bunları 'opEquals''ın gerçek gerçeklemesini anlatırken yapıyor. Programcı bu işlevleri kendisi yazarken de bu 'assert''lerin geçerli olmasını bekler miyiz?

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

May 02, 2011

Tam olarak bu şekilde yapıyor sanırım:

bool eşitMi(Object soldaki, Object sağdaki) {
   // eğer aynı nesneyi gösteriyor ya da her ikisi null (bağlanmamış) ise
   // => eşit
   if(soldaki is sağdaki) return true;
   // eğer ikisinden biri null ise => eşit değil
   if(soldaki is null || sağdaki is null) { return false; }
   // eğer ikisi de aynı türe sahipse => eşitMi'yi bir kere çağırmak
   // yeterli
   if(typeid(soldaki) == typeid(sağdaki)) return soldaki.opEquals(sağdaki);
   // son durum el sıkışma :)
   return soldaki.opEquals(sağdaki) && sağdaki.opEquals(soldaki);
}

Bu şekilde kendi yazdığımız karşılaştırmalar için de bunları yazmamıza gerek var mı acaba. Çünkü 'override' ile eskisini geçersiz hale getirmiş olduk.

Yalnız burada belirli kısımları kaldırmamız gerekiyor galiba..

Ben de tam burada konunun yarısında kalmışım :)

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

May 02, 2011

Örneğin ilk örnekte şu şekilde iki çalarsaati karşılaştırmak isteyince de hata veriyordu:

   auto değişken0 = new ÇalarSaat(6, 7, 8, 1, 4);
   auto değişken1 = new ÇalarSaat(6, 7, 8, 1, 2);

   assert(değişken0 != değişken1);

Saat ve ÇalarSaat'in karşılaştırma işlevlerini bu şekilde değiştirince yukarıdaki kod çalışıyor.

class Saat {

// ...

   override bool opEquals(Object sağdaki) const {

       // Diğer eleman bir Saat olmalı
       auto şu = cast(Saat) sağdaki;
       if (!şu) return false;
       return ((saat == şu.saat)
               &&
               (dakika == şu.dakika)
               &&
               (saniye == şu.saniye));
   }
}

class ÇalarSaat : Saat {

// ...
   override bool opEquals(Object sağdaki) const {
       // Diğer eleman bir ÇalarSaat olmalı
       auto şu = cast(ÇalarSaat) sağdaki;
       if (!şu) return false;
       return super.opEquals(şu) && alarmSaati == şu.alarmSaati
           && alarmDakikası == şu.alarmDakikası;
   }
}

Ama anladığım kadarıyla ÇalarSaat'in gözünden bakınca bir Saat kendisine eşit değil. Saat'in gözünden bakınca ve yukarıdaki tür dönüştürme işlemi ÇalarSaat'in Saat kısmını döndürdüğü için eşit olabiliyor.

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

May 02, 2011

Yalnız bu şekil sağdan soldan eşit karşılaştırmayı bu yüzden yazamıyoruz anladığım kadarıyla. Çünkü ÇalarSaat'in gözünde her zaman eşit değil çıkıyor.

Sizin yazdığınız kod da tam ayrıntılı incelemedim ama hemen hemen aynı gibi. Tek fark burada sağdaki geçerli bir nesneyi göstermiyorsa (null'sa) ya da dinamik türü Saat değilse false döndürüyor. Ama ortada 'null' bir referans göremiyorum :)

Baktıktan sonra sorun sadece 'ÇalarSaat''in 'opEquals' işlevinde

super.opEquals(o)

yerine

(super == o)

kullanılmasından kaynaklanıyor. Aslında bunlar eşit değil miydi :)

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

May 02, 2011

İyi yakalamışsın! Bu da ben yazmaya başladıktan sonra değişen konulardan birisiydi. Gösterdiğin işlev src/druntime/src/object_.d dosyasında Object sınıfının içinde tanımlı:

   equals_t opEquals(Object lhs, Object rhs)
   {
       if (lhs is rhs)
           return true;
       if (lhs is null || rhs is null)
           return false;
       if (typeid(lhs) == typeid(rhs))
           return lhs.opEquals(rhs);
       return lhs.opEquals(rhs) &&
              rhs.opEquals(lhs);
   }

Ali

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

May 26, 2011

Alıntı:

>

Ama anladığım kadarıyla ÇalarSaat'in gözünden bakınca bir Saat kendisine eşit değil. Saat'in gözünden bakınca ve yukarıdaki tür dönüştürme işlemi ÇalarSaat'in Saat kısmını döndürdüğü için eşit olabiliyor.

Erdem dünden beri opEquals işlevinde tam da bu noktada takılmış kalmıştım. Neden böyle olduğuna dair senin ulaştığın sonuca da bir türlü ulaşamadığımı belirtmem gerek. Ancak senin açıklamalarından sonra "Segmentation fault" (ayrıştırma hatası mı diyeceğiz?) hatasını giderebiliyorum.
Şimdi bu durumda nesnelerin her ikisi de ÇalarSaat nesnesi ve değerleri eşit. Ancak programımız nesnelerimizin çıktı sonucunda eşit olmadıklarını bildiriyor. Ama taşıdıkları değerler yönünden her ikisi de eşitler. Yani opEquals işleviyle bu sonuca varmamız gerekiyor.
Alıntı:

>

Yalnız bu şekil sağdan soldan eşit karşılaştırmayı bu yüzden yazamıyoruz anladığım kadarıyla. Çünkü ÇalarSaat'in gözünde her zaman eşit değil çıkıyor.

O halde opEquals işlevi ile karşılaştırma yapamayacağız demek mi oluyor bu?

Kodlarımın tamamını aşağıya ekliyorum
.

import std.stdio;
import std.string;

class Saat
{
	int saat;
	int dakika;
	int saniye;

	this(int saat, int dakika, int saniye)
	{
		this.saat   = saat;
		this.dakika = dakika;
		this.saniye = saniye;
	}

	override string toString() const
	{
		return format("%02s:%02s:%02s", saat, dakika,saniye);
	}
	/*override bool opEquals(Object o) const
	{
		auto sağdaki = cast(const Saat)o;

		return(( saat == sağdaki.saat) && (dakika == sağdaki.dakika) &&
                        (saniye == sağdaki.saniye));

	}*/
	override bool opEquals(Object o) const
	{
		/// diğer eleman da saat olmalı
		auto sağdaki = cast(const Saat) o;
		if (!sağdaki) {
			return false;
		}
		return (( saat == sağdaki.saat) && (dakika == sağdaki.dakika)
                        && (saniye == sağdaki.saniye));
	}
}

class ÇalarSaat : Saat
{
	int alarmSaati;
	int alarmDakikası;

	this(int saat, int dakika, int saniye, int alarmSaati, int alarmDakikası)
	{
		super(saat, dakika, saniye);
		this.alarmSaati   = alarmSaati;
		this.alarmDakikası= alarmDakikası;
	}
	override string toString() const
	{
		return format("%s ♫%02s:%02s", super.toString(), alarmSaati, alarmDakikası);
	}

	/*override bool opEquals(Object n) const
	{
		auto sağdaki = cast(const ÇalarSaat)n;
		return( (super.opEquals(n)) && (alarmSaati == sağdaki.alarmSaati)
				&& (alarmDakikası == sağdaki.alarmDakikası) );
	}*/
	override bool opEquals(Object o) const
	{
		/// diğer eleman da ÇalarSaat olmalı
		auto sağdaki = cast(ÇalarSaat)o;
		if (!sağdaki) {
			return false;
		}
		return ((super.opEquals(sağdaki)) && (alarmSaati == sağdaki.alarmSaati)
				&& (alarmDakikası == sağdaki.alarmDakikası));
	}
}


void main()
{
	auto değişken1 = new Saat(6, 7, 8);    // çalışıyor
	auto değişken2 = new Saat(6, 7, 8);
	//assert(değişken1 != değişken2);
	if (değişken1 == değişken2) {        // veya
		writeln("Taşıdıkları değer yönünden eşitler");
	} else {
		writeln("Eşit değiller");
	}
	auto ortak1 = new Saat(9, 10, 11);     // çalışıyor
	auto ortak2 = ortak1;
	//assert(ortak1 == ortak2);
	if (ortak1 == ortak2) {         // veya
		writeln("Eşitler");
	} else {
		writeln("Eşit değiller");
	}

	auto masaSaati1 = new ÇalarSaat(17, 15, 5, 20, 30); // son işlevde hata verdi
	auto masaSaati2 = new ÇalarSaat(17, 16, 5, 20, 30);
	assert(masaSaati1 == masaSaati2); // assertion
	if (masaSaati1 == masaSaati2) {
		writeln("masaSaati değişkenleri eşit");
	} else {
		writeln("masaSaati değişkenleri eşit değil");  // eşit olmaları gerekmiyor mu?
	}
}

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

May 26, 2011

Düzeltme:

auto masaSaati1 = new ÇalarSaat(17, 15, 5, 20, 30); // son işlevde hata verdi
auto masaSaati2 = new ÇalarSaat(17, 15, 5, 20, 30);

dünkü didişmede masaSaati2 nesnesi eşitliğin olmayacağı durumda kalmış.

auto masaSaati2 = new ÇalarSaat(17, 16, 5, 20, 30)

Şu an da eşitliği gösteriyor opEquals. Bir önceki mesajımı yok sayabilirsiniz

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

May 26, 2011

Alıntı (mert):

>

Alıntı:

>

Ama anladığım kadarıyla ÇalarSaat'in gözünden bakınca bir Saat kendisine eşit değil. Saat'in gözünden bakınca ve yukarıdaki tür dönüştürme işlemi ÇalarSaat'in Saat kısmını döndürdüğü için eşit olabiliyor.

Erdem dünden beri opEquals işlevinde tam da bu noktada takılmış kalmıştım. Neden böyle olduğuna dair senin ulaştığın sonuca da bir türlü ulaşamadığımı belirtmem gerek. Ancak senin açıklamalarından sonra "Segmentation fault" (ayrıştırma hatası mı diyeceğiz?) hatasını giderebiliyorum.

Aradan uzun zaman geçince koda şöyle bir baktım :-p O hatanın nedeni basitçe Ali bey'in

super.opEquals(o)

yerine

(super == o)

kullanmış olması. Aslında Ali beyin yazdığı kodda sadece bu değişikliği yaparsan çalıştığını göreceksin :) Neden Ali beyin yazdığı gibi çalışmıyor ben de bilmiyorum. Çünkü bunlar teorik olarak aynı şey :)

Benim eklediğim sadece null bir referansla karşılaştırmak olmuştu. O da örneğin bir ÇalarSaat nesnesi ile null yani henüz hiç bir nesneyi göstermeyen bir refaransı karşılaştırdığımızda eşit değil vermesi gerekiyor.

Alıntı:

>

Yalnız bu şekil sağdan soldan eşit karşılaştırmayı bu yüzden yazamıyoruz anladığım kadarıyla. Çünkü ÇalarSaat'in gözünde her zaman eşit değil çıkıyor.

Evet örneğin Çalarsaat'in eşitlik karşılaştırma bölümünde parametre olarak bir Saat gönderdiğimiz zaman onu Çalarsaat'e dönüştürmeye çalışıyoruz. Ama Saat'in örneğin alarmsaati gibi ek üyeleri olmadığı için bu eşit değil çıkacak. Ama Saat'e parametre olarak ÇalarSaat gönderdiğimizde tür dönüştürme ÇalarSaat aynı zamanda bir Saat olduğu için ÇalarSaat'in ek üyelerini atacak ve bir Saat döndürecek. Bu yüzden eşit çıkacak.

Orada Ali beyin gösterdiği /src/object_.d karşılaştırma işlevinin nasıl çalıştığını bilmekte de fayda var.Bu normal matematik kurallarına göre çalışıyor. Yani

x = y ise y = x

tir gibi. Kendi yazdığımız karşılaştırma işlevlerini de daha esnek yazmak isteriz. Çünkü bizim açımızdan iki çalar saat'in dakika saniye .. gibi değerleri eşitse bunlar eşittir.

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

May 26, 2011

Alıntı (acehreli):

>

'super == o' yazınca yukarıda da konuştuğumuz src/druntime/src/object_.d içindeki algoritma tekrar işletiliyor.

Olay budur :) Mert senin de bu konuyu açman çok iyi olmuş.

Bir de TDPL'de günümüz dmd derleyicileri tarafından henüz desteklenmeyen kodlar bulunabiliyor.

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

May 26, 2011

Teşekkür ederim. Tdpl için henüz erken. Ancak notumu aldım. Buradaki açıklamalar oldukça aydınlatıcı. Ben daha Ali hocamın anlattıklarını bitiremedim ki, Sonra arkasından bütün forumun tartışılmış konuları var. Adım adım ilerliyorum. Anlamadıklarımı veya çelişkiye düştüğüm yerleri burada ilgili konu başlığında sizlere soruyorum.

Zaten sizlerin olabildiğince açık ifadeleriniz de konulara başka boyutlar, farklı bakış açıları ve derinlikler kazandırıyor.

Çalışmak da keyifli olabiliyor bu haliyle. Zihninize sağlık :-)

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

« First   ‹ Prev
1 2