Ş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
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]