Bence çok güzel ve kullanışlı oluyor ama söyleyecek şeyler var. ;) Örnek programın doğru html oluşturması ne güzel, değil mi! :)
Umarım aşağıdaki kadar çok nokta seni caydırmaz. :) Ben söylemeden edemem, çünkü hepsi önemli ve bilinmesi gerekiyor.
İnan ki bu kadar sözü çok deneyimli birisinin yazdığı herhangi bir kod üzerine de söyleyebiliriz. Tasarım sırasında çok seçim yapmak gerekebiliyor ve bu seçimler üzerine her şey söylenebilir. :)
Ve bu kodu yalnızca başlangıç olarak yazdığını da biliyorum; bazı yerlerini zaten değiştirecektin... :)
- Bu kod, kodlama standardımıza tam uymamış. Özellikle işlev ayraçları ile deyim ayraçlarının kullanımı farklı.
http://ddili.org/wiki/index.php?title=Kodlama_Standard%C4%B1#Ayra.C3.A7lar
Aslında bütün standarda uymamız gerekiyor. Örneğin boşluklar da farklı olmuş:
http://ddili.org/wiki/index.php?title=Kodlama_Standard%C4%B1#Bo.C5.9Fluklar
(Can da işleçlerin etrafına boşluk koymuyor; hiç alışmadığım için bana çok sıkışık görünüyor; hem herkes boşluk koyuyor. :))
Kodun düzeni çok önemli. İnsan belirli bir düzene alışınca onun dışındakiler yanlışlıkmış gibi görünüyor. Örneğin işlevlerin sonundaki boş satır bana çok yabancı.
- Bu işlevler hemen standart çıkışa yazıyorlar. Onun yerine en azından bir string oluşturmak ve en sonunda onu çıkışa yazdırmak daha kullanışlı olacaktır.
Hatta, Can'la da konuştuğumuz gibi, aslında string bile kullanışlı olmayabilir. Çünkü öyle olduğunda CGI programımızın işleyişi sırasında bir yerde belirli bir koşula göre "şu başlığı da ekle" diyemeyiz; veya "çerez değişkenleri arasına şu değişkeni de ekle" diyemeyiz. Çünkü ya başlıklar çoktan çıkışa gönderilmişlerdir, ya da string çoktan oluşturulmuştur.
Elimizde sayfayı temsil eden bir tür olması çok daha kullanışlı olur. Ama bunu şimdilik bir kenara bırakalım. Bu konuyu kütüphaneyi kullandıkça hissedelim ve gerekirse düzeltelim
- Elemanlar arasında farklar var: bazılarını tek işlevle hallediyoruz, bazılarında ise iki çağrı gerekiyor. Örneğin bodyStart() ve bodyFinish(). Acaba o da şöyle olabilir miydi:
string body(string content)
{
return "<body>" ~ content ~ "</body>";
}
(Aslında 'body' karışıklık doğurabilir çünkü D işlevlerinin in, out, ve body anahtar sözcüklerine de benziyor.)
Ben o örnekte çıkışa yazmak yerine string döndürme yöntemini seçtim. Başka türlü de olabilirdi. Söylemek istediğim, böyle bir ikilik var: bazıları tek işlevle oluşuyor, bazıları iki.
-
header() işlevindeki etiketlerde satır kopyalama sonucunda oluştuğunu düşündüğüm bir hata var
-
Hatalı durumlarda kural: Eğer işe devam edemeyeceksek hata atmaktan başka çaremiz yoktur. header() 7 değeriyle mi çağrılmış? O durumda bir şey yapamayız: hata atmalıyız.
Kendi özel hata türümüz de atılabilir ama şimdilik Exception da yeter:
import std.string;
// ...
void header(int level, string text)
{
// ...
switch(level){
case 1: writeln("<h1>",text,"</h1>"); break;
// ...
default: throw new Exception(format("Invalid header tag value: %s", level));
}
(Kodlama standardında bahsetmemişiz ama switch'lerin case'lerini de yukarıdaki gibi switch'le aynı miktar içerletebiliriz; yoksa girinti çok fazla oluyor.)
Zaten çıkışa "ERROR" yazdırmanın hiçbir anlamı olmazdı; o, kullanıcının gördüğü sayfada çıkardı
- (Bunun senin tasarımınla doğrudan bir ilgisi yok ama örnek kodundaki kullanımdan esinleniyorum.)
Tekrar çift olarak kullanılan işlevlere dönersek: şu koda bakalım:
htmlStart();
bodyStart();
header(myLevel, "Merhaba");
bodyFinish();
htmlFinish();
Orada myLevel'in değerinin yasal olmadığını düşünelim. Eğer benim önerdiğim gibi hata atarsak, bodyFinish() ve htmlFinish() işlevleri işletilmezler. (Atılan hatalar içinde bulunulan kapsamlardan hemen çıkılmasına neden olurlar.) O yüzden kodumu şöyle yazmam gerekir:
htmlStart();
scope(exit) htmlFinish();
bodyStart();
scope(exit) bodyFinish();
header(myLevel, "Merhaba");
scope(exit)'ler, o kodların her durumda işletilmelerini garanti ederler.
Bu işlevler string() döndürseler hiç olmazsa şöyle yazılabilir:
html(body(header(myLevel, "Merhaba")));
Öyle olunca header'ın hata attığı durumda hiçbir şey yarım yazılmamış olur. Çünkü header hata attığında body'ye bile girilmez.
- Bu yeni dosyayı eninde sonunda proje dosyası olan Makefile'a eklemek gerekecek. O zaman da birden fazla dosyada main() işlevi bulunduğu için bağlama hatası (linker error) ile karşılaşacağız. Yani main olmamalı. O kodları unittest bloğu olarak yaz.
Projeyi de konsolda (veya geliştirme ortamında nasılsa) 'make' yazarak oluşturabilirsin.
Eline sağlık; güzel kodlamaya devam! :)
Ali
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]