Forum: Ders Arası RSS
Varsayılan parametre değeri olarak __LINE__ ve arkadaşları
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ı: Varsayılan parametre değeri olarak __LINE__ ve arkadaşları
__LINE__, __FILE__, __FUNCTION__, __PRETTY_FUNCTION__, ve __MODULE__ özel anahtar sözcükleri varsayılan parametre değeri olarak kullanıldıklarında çağrıldıkları yerdeki değeri alırlar.

Ben bunun yalnızca şablon parametreleri için doğru olduğunu sanıyordum:

  http://ddili.org/ders/d/sablonlar_ayrintili.html

Normal işlevler için de geçerliymiş:
import std.stdio;
 
void foo(size_t satır = __LINE__)
{
    writefln("foo içindeki satır      :%3s", __LINE__);
    writefln("çağrıldığı yerdeki satır:%3s", satır);
}
 
void main()
{
    foo();
}
Çıktısı:

foo içindeki satır      :  5
çağrıldığı yerdeki satır: 11

Kitabı daha sonra düzelteceğim.

Ali
Avatar
Salih Dinçer #2
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Bu olanağın ne işe yarayabileceğini düşünüyorum...

Sonuçta bunlar da derleme anında, tıpkı şablonlarda olduğu gibi katıştılmış bir şekilde üretiliyor. Eğer bir takım sorgu ve uyarı sistemleri için kullanılırsa, derleyici tüm kodu okuyup bizim için bu değerleri sabit (constant) olarak istediğimiz yere yerleştirecek. Ya sonra?

Örneğin...

  • Geniş bir sınıf, geliştirme aşamasında tüm üye işlevleri önceden belirlenip (Vizyoner Yaklaşım FÇB: Faydalı Çerçeve Belirleme) yazılmaya başlandıysa, satır sayısı az olanlar çalışma anında bir uyarı verip aslında işlevin döndürdüğü değerin hesaplanmadığını bildiribilir. Yani sadece üye işlevin yeri geçici olarak doldurulduğunu biliriz.
  • Hatta bu uyarı sistemi kendi kendini imha edebilir. Satır sayısı belli bir seviyeye çıktığında (örn. kodlama alışkanlığına göre değişmekle birlikte 4-5 satırdan fazlaysa) artık yeni eklenen kodların değerini döndürür.
  • Bu sistem, bu şekilde etkin değil de arkaplanda çalışan pasif bir loglama sistemi (tracer), çok basit olarak mümkün görünüyor. Öyle ki çağrılan işlevlerin isimleri ile birlikte modül ve satır numaraları (örn. bir dosyada) biriktirebilir.

Tam olarak bu maddeyi yazarken bir şeyin farkına vardım. Zaten bu parametreler, hali hazırda derleme anında çıkan hata ve uyarılarda kullanılıyor olmalı. Bu yüzden, derleyicinin bizimle bu sabitleri paylaşması çok güzel bi'şiii :)

Tabi olası hataları en aza indirmek için (Zafer Çelenk'in kulakları çınlasın) etkili mekanizmalarımız vardı diye hatırlıyorum. Zafer'in TÜDEV 2012 seminerinde anlattığı in/out blokları da çok işimize yarayabilir.

Bilmiyorum, bu sabitler başka ne işimize yarardı?
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #3
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ı
Salih Dinçer:
Zaten bu parametreler, hali hazırda derleme anında çıkan hata ve uyarılarda kullanılıyor olmalı. Bu yüzden, derleyicinin bizimle bu sabitleri paylaşması çok güzel bi'şiii :)

Aynen öyle. :) Bunlar C (ve C++) makrolarında da yararlıdır. (D'de makro yok ama benzer olarak mixin var.) C'de makro ile eklenen kod içindeki değişken isimlerin çakışmamaları (aynı olmamaları) istendiğinde örneğin, LINE değerinden yararlanılır.

Benzer durumu D'de ama uyduruk :) bir örnekle göstermek istersek:
string değişkenTanımı()
{
    return "int i = 42;";
}
 
void main()
{
    mixin (değişkenTanımı());
    mixin (değişkenTanımı());    // DERLEME HATASI
}
'i' isminde iki değişken olduğu için derleme hatası:

Error: declaration deneme.main.i is already defined

Bir çözüm, __LINE__'dan yararlanmak:
string değişkenTanımı(size_t satır = __LINE__)
{
    import std.string;
    return format("int i_%s = 42;", satır);    // <-- İsmi i_N gibi...
}
Artık derlenir çünkü iki değişkenin adları artık örneğin 'i_1000' ve 'i_1001'dir. (Tabii bu uyduruk bir örnek; o isimlerin bilinmeleri gereken durumlarda işe yaramaz. Daha güzel örnekler için C'ye bakmak gerek...)

Ali
Avatar
huseyin #4
Üye Haz 2012 tarihinden beri · 363 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
void main()
{
    mixin (değişkenTanımı());
    mixin (değişkenTanımı());    // DERLEME HATASI
}

D'nin mixin adlı özelliğinin yapısını düşünüyorum fakat işin içinden çıkamadım doğrusu. Bir bilene danışalım dedim nasıl yapıyor bunu?
Huseyin
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ı
mixin aslında çok basit: Kendisine verilen dizgiyi bulunduğu noktaya kodmuş gibi yerleştiriyor. Derleyici önce mixin'in değerini yerleştiriyor, sonra derlemeye geçiyor.

Buradaki asıl önemli olan özellik, D'nin derleme zamanında işlev işletebilmesi (CTFE). mixin'ler o zaman daha güçlü hale geliyorlar. Yukarıdaki değişkenTanımı() gibi basit dizgiler yerine olabildiğince karmaşık kodlar üretmek ve mixin ile yerleştirmek çok kolay.

Ali
Avatar
huseyin #6
Üye Haz 2012 tarihinden beri · 363 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Buradaki asıl önemli olan özellik, D'nin derleme zamanında işlev işletebilmesi (CTFE).

Anlıyorum yorumlayarak derliyorlar. Gerçekten içinden çıkamadığım bir durum benim bu belki de bakış açımı değiştirmeliyim değil mi :) Programlama dili geliştirmek gerçek bir üstadlık işi bunu anladım. D'yi de gerçek üstadlar geliştiriyor kim ne derse desin bence geleceği değiştirecek dillerden birisi olacak
Huseyin
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ı
huseyin:
Anlıyorum yorumlayarak derliyorlar.

Eğer yorumlamalı dillerin yaptığı gibi düşünüyorsak tam doğru değil çünkü gerçek anlamda derliyor. Şöyle bir kod olsun:
import std.stdio;
import std.format;
 
string toplamaİfadesi(string birinci, string ikinci)
{
    return format("%s + %s", birinci, ikinci);
}
 
unittest
{
    assert(toplamaİfadesi("elma", "armut") == "elma + armut");
}
 
void main()
{
    int a = 1;
    int b = 2;
 
    int c = mixin(toplamaİfadesi("a", "b"));
 
    writeln(c);
}
Derleyici main işlevini derlerken bir mixin'le karşılaşıyor. Koda ne katacağını bilmesi için mixin'in içindeki ifadeyi işletmesi gerekir.

toplamaİfadesi()'ni "a" ve "b" ile çağırabilmesi için toplamaİfadesi'nin derlenmiş olması gerekir. (Belki daha önceki bir mixin veya şablon tarafından da gerekmiştir ve o yüzden zaten derlenmiştir. Veya, bu ilk ihtiyaçtır ve o yüzden daha derlenmemiştir.)

toplamaİfadesi derleniyor, derlenmiş olan işlev çağrılıyor ve o "a + b" dizgisini döndürüyor.

mixin'e verilen o dizgi main'e katılınca işlev şu hale geliyor:
    int a = 1;
    int b = 2;
 
    int c = a + b;
 
    writeln(c);
Derleyici şimdi de o kodu derliyor. Yani, aslında karmaşık bir konu değil: Derlerken gereken başka kodla karşılaşınca önce o kodu derliyor.

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:
Forum: Ders Arası RSS
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, 02:51:53 (UTC -08:00)