Forum: Projeler turna RSS
Başlık satırlarının oluşturulması
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ı: Başlık satırlarının oluşturulması
Şimdi başlık satırlarını yalnızca işlev kullanarak yapmaya başladım ve hemen bir sorunla karşılaştım.

Bildiğimiz gibi, başlık satırları satırın isminden ve sonrasında gelen değişken isimlerinden ve değerlerinden oluşuyor:

Bir-Başlık: değişken0=değer0; değişken1=değer1; değersiz-değişken

Emin olamadığım bir konu, değişkenlerin sıralarının önemli olup olmadığı. Örneğin Set-Cookie satırlarındaki HttpOnly her zaman için en sonda mı gelmeli? (Bence sıra önemli değildir.)

O sorunun yanıtı ne olursa olsun değişkenlerin belirli bir sırada çıkmalarının önemli olduğunu varsayalım. Eğer eşleme tablosu kullanırsak sıralar konusunda bir şey söyleyemiyoruz:

string headerLine(string name, string[string] variables)

Çünkü variables isimli eşleme tablosunun elemanları belirsiz sırada çıkarlar. O olmaz...

O zaman D'nin belirsiz sayıda parametre gönderme olanağından yararlanabiliriz; bu durumda dizi kullanmak zorundayız çünkü belirsiz sayıda parametreler dizi olarak gelirler:

string headerLine(string name, HeaderVariable[] variables ...)

Söylemek istediğim, yukarıda yazdığım gibi bir HeaderVariable türüne ihtiyacımız var. Değil mi? Derleyici tekrarladığımız şeyin bir şey olmasını istiyor.

Kendi söylediğimi yalanlama pahasına; aslında belirsiz sayıda string almak da olur:

string headerLine(string] name, string[] variables ...)

Ama o her değişkenin isim+değer çiftinden oluştuğu durumda kullanışlı olabilir. Böylece assert((variables.length % 2) == 0) diye denetleriz ve işimize devam ederiz. Ama ya arada değersiz bir değişken varsa? Onun tek bir isimden oluştuğunu anlayabilir miyiz?

Hmmm. Aslında onun için de değer olarak null girilmesini şart koşabiliriz:

    headerLine("name",
               "one", "two",       // bir değişken
               "no-value", null,   // değeri olmayan bir değişken
               "three", "four");   // başka değişken 

Ama o bana idare etmesi ve okuması daha zor geliyor. Çok sayıdaki parametreden hangi ikilerinin isim+değer olduklarına dikkat etmek gerek. Bir programcı değeri olmayan bir değişkeni null'ını unutarak yazsa ondan sonraki çiftlerin eşleşmeleri bozulur.

Yukarıdakilerin hiçbirisi üstesinden gelinemeyecek sorunlar değil ama HeaderVariable gibi bir türümüz olsa headerLine şöyle çağrılabilir:

    headerLine("name",
               HeaderVariable("one", "two"),
               HeaderVariable("no-value"),
               HeaderVariable("three", "four"));

Bana çok daha açık geliyor. Size de mantıklı gelmiyor mu? Eğer kabul ederseniz düşündüğüm şöyle:

struct HeaderVariable
{
    string name;
    string value;
 
    string toString() const
    {
        string result = name;
 
        if (value !is null) {
            result ~= '=' ~ value;
        }
 
        return result;
    }
}
 
string headerLine(string name, HeaderVariable[] variables ...)
{
    return name.idup ~ ": " ~ printWithDelimiter(variables, "; ");
}

printWithDelimiter, kendisine verilen elemanların aralarına ayraç yerleştiren bir işlev:

string printWithDelimiter(T)(T[] array, string delimiter)
{
    string result;
 
    /* No delimiter before the first one */
    if (array.length) {
        result ~= to!string(array[0]);
        array = array[1 .. $];
    }
 
    foreach (element; array) {
        result ~= delimiter ~ to!string(element);
    }
 
    return result;
}

Artık başlık satırlarını oluşturmak kolay. Örneğin Set-Cookie şöyle oluşturulabilir:

string cookieLine(string name, string data,
                  long expiresIn = 0,
                  string path = null,
                  string domain = null,
                  bool httpOnly = false)
{
    HeaderVariable[] variables = [ HeaderVariable(name, data) ];
 
    if (path !is null) {
        variables ~= HeaderVariable("path", path);
    }
 
    if (expiresIn != 0) {
        variables ~= HeaderVariable("Max-Age", to!string(expiresIn));
    }
 
    if (domain !is null) {
        variables ~= HeaderVariable("domain", domain);
    }
 
    if (httpOnly) {
        variables ~= HeaderVariable("HttpOnly");
    }
 
    return headerLine("Set-Cookie", variables);
}

Başlık satırlarının oluşturulması sırasında "; " ve "=" karakterlerini de tekrarlamıyoruz. Onlar tek bir yerde geçiyorlar. Bence bu konudaki yardım HeaderVariable denen yapıdan geliyor.

Ali
canalpay (Moderatör) #2
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ı
Bana çok daha açık geliyor. Size de mantıklı gelmiyor mu? Eğer kabul ederseniz düşündüğüm şöyle:

Kesinlikle mantıklı. O kadar çok parametre tanımlanacaksa bence kesinlikle bir tür tanımlamak gerekir. Yada direk tek string içinde göndermek gerekir.

Ya header("Location: http://mesela.dom/");
Ya da sizin dediğiniz gibi.

Bence sizin dediğiniz gibi olması çok daha iyi.

Tek anlaşmamız gereken yer cookie tanımlamaya yarayan işlevin adı cookieLine değil setCookie olacak :-p

Birde header modülünde acaba çıkışa alınan headerların listesini alma ve header tanımlama alanından çıkıp çıkmadığını öğenme işlevleri yazılabilir mi?
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ı
canalpay:
Ya header("Location: http://mesela.dom/");

O yeterli bir soyutlama değil çünkü başlığın isminden sonraki ':' karakterini ve değişken değerlerinden önceki '=' karakterlerini işlevi çağırana bırakıyor.

Eğer bütün satırı kullanıcı yazacaksa bir string verelim, sonuna eklesin.

Onun yerine şöyle bir soyutlama düşünsek:

    sayfa.başlıkDeğişkeniEkle("şu-başlık", Değişken("isim", "değer"));

Orada yapılan iş, "sayfanın şu başlık satırına şu değişkeni şu değerle eklemektir." Yani olay sayfanın satırını oluştumaktan çıkmış ve sayfa, başlık satırı, değişken, değer, vs. gibi kavramlar haline gelmiştir.

Satır, o kavramların HTML standardının öngördüğü düzende gösterimidir. Yani o, en son olarak sayfayı göstermek istediğimizde kullanılacak düzendir. Yoksa örneğin program içindeyken "şu başlığın şu değeri neymiş" dediğimizde satırı tekrar tekrar ayrıştırmak gerekir.

Tek anlaşmamız gereken yer cookie tanımlamaya yarayan işlevin adı cookieLine değil setCookie olacak :-p

setCookie olması için Cookie diye bir şeyin olması gerekir. Eğer şimdiki halinde olduğu gibi "başlığın cooke satırını" oluşturuyorsak o cookie değil, bir başlık satırıdır.

setCookie olabilmesi için daha sonradan tekrar çağırıp cookie'yi değiştirebiliyor olmalıyız. Ama satırı oluşturup yazdıktan sonra öyle bir şansımız kalmıyor. Yani biz cookie'yi değil, cookie satırını oluşturuyoruz.

O yüzden bu haliyle olsa olsa setCookieLine() olabilir.

Birde header modülünde acaba çıkışa alınan headerların listesini alma ve header tanımlama alanından çıkıp çıkmadığını öğenme işlevleri yazılabilir mi?

Güzel sorular. :) O sorular da yazdığımız işlevlerin çıkışı oluşturmak yerine sayfayı oluşturmaları gerektiğine işaret ediyorlar. Programcının işi dilin olanaklarını kullanmak olmalı. Örneğin sayfa bir string olarak oluşturulmamalı. Yoksa baştan sona tarayıp ayrıştırma işleriyle uğraşmak zorunda kalırız. Onun da D dili ile pek ilgisi yoktur.

Ama Sayfa diye bir sınıf olsa zaten başlık alanından çıkma diye bir sorun söz konusu olamaz çünkü o bölümü Sayfa sınıfı oluşturur.

Başlıklar hakkında bilgi edinmenin bir yolu:

    Başlık[] şuAndakiBaşlıklar = sayfa.başlıklar();

şeklinde olabilir.

En sonunda ve ancak sayfanın tamamlandığını düşündüğümüzde bütün sayfayı toString() benzeri bir işlevle oluşturmak çok daha yararlı olur.

Ali
canalpay (Moderatör) #4
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ı
O yeterli bir soyutlama değil çünkü başlığın isminden sonraki ':' karakterini ve değişken değerlerinden önceki '=' karakterlerini işlevi çağırana bırakıyor.
Doğru. Öylesine demiştim.

Onun yerine şöyle bir soyutlama düşünsek:
.
..
...

bir türde saklamak daha mantıklı geliyor bana. Çünkü iki parametrede birbiriyle alakalı ancak burada alaka bulundurmuyor. Tabii sizin önceki fikir yerine önerdiğinizi biliyorum. Bende size katıldığımı söylemek için yazıyorum.

setCookie olması için Cookie diye bir şeyin olması gerekir. Eğer şimdiki halinde olduğu gibi "başlığın cooke satırını" oluşturuyorsak o cookie değil, bir başlık satırıdır.

Bilgisarımızdaki o dosyalara benim bildiğim cookie deniyor. Yani bir kod ancak cookie oluşturan bir kod.

setCookie olabilmesi için daha sonradan tekrar çağırıp cookie'yi değiştirebiliyor olmalıyız. Ama satırı oluşturup yazdıktan sonra öyle bir şansımız kalmıyor. Yani biz cookie'yi değil, cookie satırını oluşturuyoruz.
Aslında değiştiriyoruz sayılır. Tabii bir c ve türevi çalışanlar için bunu kanıtlayamam :-p Onlar için bir şeyi silip aynı adda başka bir şey yapıyoruz. Ama bence buna değiştirmek denir :-)

Ayrıca setCookie uluslar arası standarttır herhalde :-p Tabiki yine siz bilirsiniz. Sizin dediğiniz benim dediğimden daha mantıklı.

Ama Sayfa diye bir sınıf olsa zaten başlık alanından çıkma diye bir sorun söz konusu olamaz çünkü o bölümü Sayfa sınıfı oluşturur.

web programlamada her zaman cookie ile uğraşırlar sanırım. Onun için o bile kesin olarak garantileyemez bence. Daha kesin bir çözüm yolu?

Doğrusu MVC tasarımı sayesinde cookie sorunu pek oluşmaz. Header modülünü istediğiniz gibi oluşturabilirsiniz. Zaten gereksiz bir şey görürsek çıkartır, gerekli bir şey görürsek ekleriz.
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: 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-11-21, 09:19:05 (UTC -08:00)