Forum: Projeler turna RSS
Helper Tasarımı
Sayfa:  1  2  3  sonraki 
Kadir Can #1
Üye Haz 2010 tarihinden beri · 413 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Helper Tasarımı
Sizce helper işlevlerini yaparken her html elmanı için bir işlev mi yazmalıyım,yoksa kullanılacak değeri almalı mıyım?

Yani;
mesela <br /> = altaGeç() mi olsun?
Yoksa html("br") gibi mi kullanalım?

Bence birincisi daha iyi duruyor.
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4481 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Kesinlikle birincisi daha iyi. Yoksa her kullanıcının "br"yi bilmesi gerekir ve olasılıkla yanlış yazabilirler.

Küçük ölçekte de olsa kod tekrarıdır: "br" tekrarlanmaktadır.

İsmi ayrı bir soru: br() bile olabilir; veya break()? (Bu durumda yanlış yazmak sorun değil, çünkü derleyici izin vermez.)

Ali
Kadir Can #3
Üye Haz 2010 tarihinden beri · 413 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Anladım.Zaten öyle tasarlamıştım. :D

Temel bir modül yazıp ekledim.Acaba bir bakar mısınız?Oluyor mu?Oluyorsa yarın devam ederim.
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4481 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
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.…?title=Kodlama_Standard%C4%…

Aslında bütün standarda uymamız gerekiyor. Örneğin boşluklar da farklı olmuş:

  http://ddili.org/wiki/index.…?title=Kodlama_Standard%C4%…

(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
Kadir Can #5
Üye Haz 2010 tarihinden beri · 413 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Dedikleriniz oldukça önemli.Kodlama standartlarına uyacağım bundan sonra.Maalesef iki senedir kötü bir alışkanlığım var ama kırmam gerekiyor.

Şu string olayı oldukça mantıklı, hatta class işine girersek bayağı rahat ederiz.Ama sanırım canalpay class istemiyor.Bunu onunla da konuşabiliriz.Mesela content adında bir değişken oluştururuz ve o bütün komutlar hallolduktan sonra html kodunu content'den çağırırız.Böylece bazı işlevlerin start ve finish gibi tekrarlanmasını önleriz.Global değişken kullanmak da işe yarayacaktır sanırım.Global değişkenle bu işi hallederim.Çıkışa yazdırmaktaki amacım,kodu direk görmekti ama unittestlerle halledebiliriz.

Header'a yanlış değer verildiğinde "ERROR" çıktısı vermesini sağlamıştım ama dediğiniz gibi hata atmak mantıklı.Bunu da yapacağım.

main normalde kalkacak.Sadece denemek için var ama onu da unittestlerle hallederiz.

Teşekkürler.
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ı
Ama sanırım canalpay class istemiyor.

Benim istemediğim yer farklı.

Benim istemediğim yerde durmadan o işlevi tek bir amaçta kullanacağız. Bu işe bence tamamen classlı structlı olmalı.

Global değişken kullanmak da işe yarayacaktır sanırım.Global değişkenle bu işi hallederim.Çıkışa yazdırmaktaki amacım,kodu direk görmekti ama unittestlerle halledebiliriz

Nedenini çok iyi bilmiyorum ancak global değişken kullanmak çok yanlış bir davranış olarak nitelendirilir.(Tahminen her tarafta değiştirildiği için değişkenin değişimini izleyemiyoruz. Birde belleksel anlamda da sıkıntılara neden olabiliyordur?)

Birde senin modülü koyduğun yer yanlış... Helper klasör ismi olacaktı. Ali Bey tabiki onun için daha güzel bir ad bulmasını isteyeceğiz. Artık bende helper adının yavan kaldığını düşünüyorum. Daha güzel bir isim bulana kadar yolu system/helper/modüladı.d'de saklanacak. Modül adı htmlHelper olabilir.(daha güzel bir ad önerilene kadar.)
acehreli:
- 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.

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));
}

Ali bey sanki ben böyle hata atmayı denemiştim ancak hata çıktısı gözükmüyordu. Sizde denemiş miydiniz?
acehreli (Moderatör) #7
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4481 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #5
Kadir Can:
sonra html kodunu content'den çağırırız

Aynı fikirdeyim. :)

Ali
acehreli (Moderatör) #8
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4481 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #6
canalpay:
global değişken kullanmak çok yanlış bir davranış olarak nitelendirilir.(Tahminen her tarafta değiştirildiği için değişkenin değişimini izleyemiyoruz.

Doğru. Giderdiği düşünülen hemen hemen her ihtiyaç yerel bir değişkenle de halledilebilir. Ama stdin gibi akımlar geleneksel olarak global değişkenlerdir. (İnatla öyle yapmayan diller de var.)

Birde belleksel anlamda da sıkıntılara neden olabiliyordur?)

C ve C++'da, farklı derleme birimlerindeki global değişkenlerin hangi sırada ilklendikleri belirsizdir. Birisi, kendi ilklenmesi sırasında ötekisini kullanmaya çalışsa henüz ilklenmemiş bir nesneyi kullanıyor olabilir:

BenimGlobal::BenimGlobal()
{
    global_log_nesnesi.logla("BenimGlobal kuruluyor")// <-- Belki de hata
}

D'de bu çok daha iyi durumdadır: modüllerin birbirlerini "import etmeleri"ne bakarak hangisinin hangisine bağımlı olduğu anlaşılır ve globaller ona uygun olarak ilklenirler.

Helper klasör ismi olacaktı. Ali Bey tabiki onun için daha güzel bir ad bulmasını isteyeceğiz

Bu sınıflar html oluşturduklarına göre klasör ismi html mi olsun? Veya sayfayı oluşturdukları için page? html_page?

htmlHelper olabilir

Tamam; güzel.

Ali bey sanki ben böyle hata atmayı denemiştim ancak hata çıktısı gözükmüyordu

Hatanın tarayıcı tarafındaki kullanıcıyla ilgisi yok. Onun için programcının (root olarak) /var/log/apache2/error.log dosyasına bakması gerekiyor. Programın stderr akımına gönderdiği bütün çıktı oraya yazılıyor.

Daha önceki tahminim de yanlışmış: sayfa yarım oluşturulmuşken hata atıldığında programımız sıfırdan farklı bir hata koduyla sonlandığı için Apache tarayıcıya yarım çıktıyı göndermiyor.

Apache'nin "bir hata oldu" gibi genel hatası yerine, programcı hatayı en dışarıda main'de yakalayabilir ve "özür dileriz falan filan" gibi basit bir sayfa da kurabilir.

Ali
canalpay (Moderatör) #9
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ı
Bu sınıflar html oluşturduklarına göre klasör ismi html mi olsun? Veya sayfayı oluşturdukları için page? html_page?
Belki tek html ile sabit kalmayacak ise?

Apache'nin "bir hata oldu" gibi genel hatası yerine, programcı hatayı en dışarıda main'de yakalayabilir ve "özür dileriz falan filan" gibi basit bir sayfa da kurabilir.
Bence:
Hata yakalanacak. Ekrana hata yazılacak. Hata değişkenleri tanımlanacak. Türkçe için Türkçe İngilizce için İngilizce. Japonca için ileride Japonca :-)
acehreli (Moderatör) #10
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4481 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
canalpay:
Belki tek html ile sabit kalmayacak ise?

HTML belgeleri XML elemanlarından oluşur. Bir tane XML elemanı sınıfına ihtiyaç var. O XML elemanlarının <br>, <p>, vs. gibi isimlerle ve belirli bir yapıda bir araya gelmeleri HTML'i oluşturur. Böyle bakınca CGI programının kullanacağı elemanların HTML olduğu görülüyor.

XML elemanlarından oluşan üst düzey başka kavramlar tanımlanabilir ama onlar HTML'den ayrı anlamda olurlar.

Ekrana hata yazılacak.

Bunu biliyorsun ama bütünlük amacıyla tekrarlıyorum: CGI programının ekranı yok. Standart giriş, çıkış, ve hata akımları Apache'nin elinde bulunuyor. Bizi başlattığı zaman kendi akımlarıyla başlatıyor.

stdin'den POST yönteminin verileri geliyor; stdout'a yazılanlar HTML belgesini oluşturuyorlar; stderr'a yazılanlar hata mesajları dosyasına (varsayılan /var/log/apache2/error.log) gidiyor.

CGI programı sırasında oluşan hataların tarayıcıyı kullanan kişiyle bir ilgisi yok; ona bir şey ifade etmiyorlar. Örneğin "geçersiz başlık düzeyi" ne demek? :)

Kullanıcı bir tuşa tıklıyor, biz sayfayı oluşturmayı beceremiyoruz. Ne yapalım... :-/ Bazı durumlarda idare edebiliriz: örneğin başlık düzeyini otomatik olarak 1..7 aralığına indirebiliriz; ama bu konuda bir hata mesajı oluştururuz. Bence en iyisi de bu olur. Sayfanın düzeni bozuk olsa da hiç olmazsa bilgi tarayıcıya ulaşmış olur.

Önceki önerimi geri çekebilirim yani. :) Başlık oluşturan kod idare etmeli.

Kurtarılamayan durumlarda da tek bir "sunucuda hata oldu" anlamında bir mesaj da olabilir. Şu hata kodları standart:

  http://www.w3schools.com/tags/ref_httpmessages.asp

Apache'ye hangi hata durumunda hangi sayfanın gösterileceği söylenebiliyor. Örneğin ddili'nde 404 için şu sayfa var:

  http://ddili.org/boyle_bir_sayfa_yok

Ali
canalpay (Moderatör) #11
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ı
Bunları bilmeden konuşuyorum:

HTML belgeleri XML elemanlarından oluşur. Bir tane XML elemanı sınıfına ihtiyaç var. O XML elemanlarının <br>, <p>, vs. gibi isimlerle ve belirli bir yapıda bir araya gelmeleri HTML'i oluşturur. Böyle bakınca CGI programının kullanacağı elemanların HTML olduğu görülüyor.

XML elemanlarından oluşan üst düzey başka kavramlar tanımlanabilir ama onlar HTML'den ayrı anlamda olurlar.

Javascript. Bazı yeni web teknolojileri. Kolay dosya upload sistemi ... library sadece cgi programlama için gerekli işlevlerin tanımlanma alanı. Eğer library adı buna uymuyorsa daha iyi bir ad düşünebiliriz. En basitinden libraryOfCgi gibi.

CGI programı sırasında oluşan hataların tarayıcıyı kullanan kişiyle bir ilgisi yok; ona bir şey ifade etmiyorlar. Örneğin "geçersiz başlık düzeyi" ne demek? :)

Ancak benim bildiğim kadarıyla mvc tasarımına sahip frameworkler olsun direk programlama dilleri olsun standart çıkışa hata mesajlarını yazdırıyor.

Yine sizin gösterdiğiniz bağlantıya çok iyi göz atmadan apache'nin programsal hata değilde sunucu hatalarını oraya kayıt altına aldığını düşünüyorum.
canalpay (Moderatör) #12
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ı
(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. :))

Bana taşlama geldi bende düzeltim dedim :-) Değişiklikler : https://github.com/canalpay/turna/commit/086f6c3f1b9d4c088…

Bu arada şöyle kodlar gözüme daha hoş gözüktüğünü itiraf edeyim bende :
 
if(a==b){
    writeln("a=b");
}else{
    writeln("a!=b");
}
acehreli (Moderatör) #13
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4481 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Bunlar kişisel konular.

Ben özellikle şuradaki < karakterinin etrafında boşluk aradım:

    while(firstPost.length<to!int(getenv("CONTENT_LENGTH"))){
        
        firstPost~=din.getc;
 
    }

Benim şu sıralarda alıştığım düzende şöyle oluyor:

    while (firstPost.length < to!int(getenv("CONTENT_LENGTH"))) {
        firstPost ~= din.getc;
    }

Altı boşluk ekledim, iki satır çıkarttım. Boş satırlar metin içlerindeki paragraflar gibi oluyor. Yakın anlamdaki satırları bir arada yazıyoruz ama tek satırın etrafına boşluk yazmıyoruz.


Ali
Kadir Can #14
Üye Haz 2010 tarihinden beri · 413 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Dosyayı hallettim ancak helper.d'yi olduğ yerden silemedim.Yapabilir misiniz?

Hallettim.Şimdi kodlamaya devam.
Bu mesaj Kadir Can tarafından değiştirildi; zaman: 2011-02-16, 09:58.
canalpay (Moderatör) #15
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ı
Bende git'i daha pek iyi çözemedim ancak beğendim.

silmek için git rm dosya

sonra dosya eklemiş gibi göndereceksin.

mesajı değiştirmiş.

Şimdi geriye dönelim. Ali Beyin dediği gibi. main işlevini kaldır. module adını system.helper.htmlHelper olarak değiştir. modülü daha sınıflı daha structlı daha cicili yaz :-p (Biz git için mesajlarıda ingilizce yazıyoruz.)

Ali Beyin yazdığını olduğu gibi örnek alabilirsin: http://ddili.org/forum/thread/456
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:
Sayfa:  1  2  3  sonraki 
Forum: Projeler turna 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-09-25, 15:25:04 (UTC -07:00)