Forum: D Programlama Dili RSS
assert yerine enforce
acehreli (Moderatör) #1
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: assert yerine enforce
Program örneklerinde hep assert kullanmıştık ve kullanıyoruz...

Ben onun yerine std.contracts modülündeki enforce'un kullanıldığını da görüyorum. assert ile hemen hemen aynı anlama geliyor ve aynı şekilde kullanılıyor.

Burada "kanunu uygulamak, mecbur bırakmak" gibi bir anlama geliyor. Amaca assert'ten biraz daha uygun; çünkü assert'ün "üzerine basarak belirtmek" gibi bir anlamı var.

Alexandrescu forumda şaka olarak "enforce'u öğrenmek için kitabı okuyun" demiş. Phobos'ta her tarafta da bol bol kullanılıyor.

assert'ten benim gördüğüm bir temel farkı var:

assert'ün attığı core.exception.AssertError yerine, object.Exception atıyor. Sanırım böylece Exception'ı yakalayan yerler onu da yakalayabiliyorlar. Programlarda atılan diğer hatalardan ayrı bir sıra düzende duran core.exception.AssertError'ın catch ile ayrıca yakalanması gerekmemiş oluyor. (Denedim: gerçekten de enforce hataları catch (Exception) bloklarıyla yakalanabiliyor; assert hataları ise yakalanamıyor.)

import std.contracts;
 
double hesap_enforce_ile(double a, double b)
in
{
    enforce(b != 0, "sıfıra bölme hatası");
}
body
{
    return a * 7 / b;
}
 
void main()
{
    hesap_enforce_ile(1, 0);
}

Tabii ki yalnızca in, out, ve invariant bloklarında değil; her yerde de kullanılabiliyor.

Ali
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
enforce'u "koşul geçersizse hata at"ın kısaltması olarak düşünmek daha doğru. assert'ün de hata atıyor olması ikisini birbirine karıştırmamalı.

if (toplam < 0) {
    throw new Exception("toplam eksi olamaz");
}

yerine:

enforce(toplam >= 0, "toplam eksi olamaz");

assert ise programda kesinlikle doğru olması gereken koşullar için kullanılmalı. Çok yakın kavramlar aslında... :/

Ali
canalpay (Moderatör) #3
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Belki assert programın oluşturacağı hataları denetlemek için kullanmalıyız. Çünkü zaten program hataları kesinlikle doğru olması gereken şeylerin doğru olmama sonucunda ortaya çıkar.

enforce ise daha çok girişten verilen yanlış bilgiler nedeniyle program hata verirse kullanılmalı.

Ben kendi adıma böyle anladım.

Ama assert yerine enforce çok mu gerekli bence hayır. Özellikle :
if (toplam < 0) {
    throw new Exception("toplam eksi olamaz");
}

böyle bir kullanımda varken gereksiz.
Mengu (Moderatör) #4
Kullanıcı başlığı: NONSERVIAM
Üye Tem 2009 tarihinden beri · 347 mesaj · Konum: Dersaadet
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
assert test icin kullanilmiyor mu?
http://www.mengu.net - some kind of monster
acehreli (Moderatör) #5
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #3
canalpay:
Ben kendi adıma böyle anladım.

Ben de öyle anlıyorum.

Başka bir farkları: assert'ler, -release derleyici seçeneği ile derleyince programa dahil edilmiyorlar. enforce ise programa her zaman için dahil ediliyor.

Ali
canalpay (Moderatör) #6
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #4
assert test icin kullanilmiyor mu?

unittestin içinde yazmak şart değil. assert'de D'nin normal anahtar sözcüklerinden biri. Ama unittest ile birleşimi ile çok daha iyi oluyor.
acehreli (Moderatör) #7
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #4
Mengu:
assert test icin kullanilmiyor mu?

C'den beri hep "kesinlikle doğrudur" şeklindeki denetimler içindi. Sanırım NDEBUG makrosu tanımlandığında, yani programın release hali oluşturulurken, assert'ler programdan çıkartılırlardı.

Bunlar D'de de geçerli.

D'de assert'ler ayrıca in, out, ve invariant bloklarında sözleşmeli programlama (contracts) için; ve unittest bloklarında birim testleri için.

Özellikle programdan çıkartılabiliyor olmaları nedeniyle her duruma zaten uygun değiller. Phobos'ta gördüğüm kadarıyla, işlevlerin programdan çıkartılmamaları gereken sözleşmeleri için de kullanılıyor.

class BağlıListe
{
    void baştakiniSil()
    {
        enforce(elemanAdedi > 0);
        // ...
    }
}

Orada, işlevin devam edebilmesi için listede eleman olması gerekir. Orada assert kullanmak, assert'ün o bir sürü anlamı nedeniyle doğru gelmiyor.

Benim daha da anladığım bu... :)

Ali
Bu mesaj acehreli tarafından değiştirildi; zaman: 2010-06-16, 14:35.
acehreli (Moderatör) #8
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Walter Bright'ın bir forum yazısından çeviriyorum:

Sözleşmeler (contracts), programın tasarlandığı gibi bir durumda bulunup bulunmadığını denetlemek içindir. Sözleşme denetiminin geçersiz olması, bir program hatasıdır. (Ali'nin notu: yani "programcı" hatasıdır).

Hatalar ise, çalışma zamanında ters gidebilen şeylerdir. Örneğin dosyaya yazarken disk dolmuştur... Bunlar program hataları değildir.

Başka bir bakış açısıyla; program, sözleşme ile ilgili olan bütün satırlar çıkartıldığında da doğru olarak işleyebilmelidir. Aynısını hatalarla ilgilenen satırlar için söyleyemeyiz.

Dahası, programlar hatalı durumlardan kurtulabilirler. Sözleşme geçersizlikleri ise her zaman için ölümcüldür. Yeni başlayanlar (ve bazı uzmanlar) sözleşme hatalarından kurtulunabileceği gibi bir yanılgı içine düşebilirler. Bu, güvenli ve güvenilir bir sistemin nasıl tasarlanması gerektiği ile ilgili temel bir yanılgıdan kaynaklanır.

Ali
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-22, 05:06:48 (UTC -08:00)