Jump to page: 1 25  
Page
Thread overview
JSON Ayrıştırıcı Sınıfları
May 26, 2012
Salih Dinçer
May 26, 2012
Salih Dinçer
May 27, 2012
Salih Dinçer
May 27, 2012
Salih Dinçer
May 27, 2012
zafer
May 27, 2012
Salih Dinçer
May 28, 2012
Salih Dinçer
May 28, 2012
Salih Dinçer
May 28, 2012
Salih Dinçer
May 28, 2012
Salih Dinçer
May 28, 2012
Salih Dinçer
May 29, 2012
zafer
May 29, 2012
Salih Dinçer
May 29, 2012
Salih Dinçer
May 29, 2012
zafer
May 29, 2012
Salih Dinçer
May 30, 2012
Salih Dinçer
May 30, 2012
Salih Dinçer
May 30, 2012
Salih Dinçer
Jun 04, 2012
Salih Dinçer
Jun 05, 2012
Salih Dinçer
Jun 05, 2012
Salih Dinçer
Jun 05, 2012
Salih Dinçer
May 28, 2012
zafer
May 29, 2012
Salih Dinçer
May 29, 2012
Salih Dinçer
May 29, 2012
Salih Dinçer
May 27, 2012

Merhaba,

Biz D'de, JSON kullanırken, Jeremie Pelletier'in geliştirdiği std.json (https://github.com/D-Programming-Language/phobos/blob/master/std/json.d) sınıfını kullanıyoruz. Kuşkusuz bunun fazla geliştirilmediği (-örn. JSONException), Linux için bazı hatalar içermesi (-bknz. ilgili inceleme (http://ddili.org/forum/post/5406)) ve kullanırken başka olanaklara ihtiyacımız olması yeni sınıflara ihtiyaç doğuruyor. Belki yapacağımız çalışmalar ileride bu sınıfın daha çok gelişmesini sağlayabilir. Açıkçası, Phobos kütüphanesi içinde biz Türkler'den bir şey bulunması gurur verici olurdu...:)

Bu konuda Ali hocamın şurada (http://ddili.org/forum/post/5382) geliştirdiği ve olduğu gibi aşağıya naklettiğim sınıf çok işimize yarıyor. Ben kendi sınıflarım için 'sdb.dene' (sdb dizini içinde) tasnifleme yapıyorum. Ama hiç biri Ali hocamın yaptığı gibi nitelikli değiller. O yüzden 'ali.json' isminde bir sınıf üzerinde, hep birlikte geliştirmeyi öneriyorum.

'Ekleme: Hemen aşağıdaki sınıfları eklemeyi unutmuşum...'

import std.stdio;
import std.conv;
import std.json;
import std.traits;
import std.exception;
import std.string;

/* Gözlem: Ne to() bizim işlevimiz, ne de JSONValue bizim türümüz. İkisini
* birleştiren böyle bir işleve hakkımız var mı? Veya: Bize mi kalmış? Aslında
* evet, çünkü eklediğimiz bu işlev kendi modülümüzün isim alanına
* ekleniyor. Karışıklık olursa da tam ismiyle ötekisi tam ismiyle örneğin
* std.conv.to diye çağrılabilir.
*
* (Not: C++ olsa std isim alanına bir şey eklenmesine izin verilmez. (Ama
* kendi türlerimizden oluşan std::pair'leri << ile yazdırmak için bazen
* mecbur kalınır.))
*
* UYARI: Eşleme tabloları unutulmuş!
*/
JSONValue to(Hedef : JSONValue, T)(T değer)
{
   JSONValue json;

   static if (isSomeString!T) {
       json.type = JSON_TYPE.STRING;
       json.str = std.conv.to!string(değer);

   } else static if (is (T : long)) {
       static if (is (T == ulong)) {
           /* std.json long türünü kullandığı için ulong'un bazı değerlerini
            * tutamaz. Güvenlik amacıyla bu durumu denetlemek için ulong için
            * ayrı bir 'static if' koşulu yazıyoruz. */
           enforce(değer <= long.max,
                   format("Veri kaybı: Bir %s değeri olan %s, long'a sığamaz!",
                          T.stringof, değer));
       }

       json.type = JSON_TYPE.INTEGER;
       json.integer = değer;

   } else static if (is (T : real)) {
       json.type = JSON_TYPE.FLOAT;
       json.floating = değer;

   } else static if (isArray!T) {
       json.type = JSON_TYPE.ARRAY;

       foreach (eleman; değer) {
           json.array ~= to!JSONValue(eleman);
       }

   } else static if (__traits(compiles, cast(JSONValue)değer)) {
       json = cast(JSONValue)(değer);

   } else {
       static assert(false,
                     "Bu tür JSONValue'ya dönüştürülemez: " ~ T.stringof);
   }

   return json;
}

unittest
{
   import std.typetuple;

   /* ulong'un değer aralığının üst yarısı long'a sığmaz. Onun için ayrıca
    * deniyoruz. */
   to!JSONValue(cast(ulong)0);
   to!JSONValue(cast(ulong)long.max);

   /* Güvenlik gerçekten işe yarıyor mu? */
   bool hataAtıldı_mı = false;
   try {
       to!JSONValue(ulong.max);

   } catch (Exception) {
       hataAtıldı_mı = true;
   }
   enforce(hataAtıldı_mı, "ulong.max için hata atılmadı!");

   /* Her temel tür kullanılabilmeli. */
   alias TypeTuple!(byte, ubyte, short, ushort, int, uint, long, /* ulong, */
                    float, double, real,
                    string, wstring, dstring, char[], wchar[], dchar[],
                    int[])
       Türler;
   foreach (Tür; Türler) {
       to!JSONValue(Tür.init);
   }
}

struct Öğrenci
{
   string isim;
   ulong numara;
   uint[] notlar;

   JSONValue opCast(T : JSONValue)() const @property
   {
       JSONValue[string] üyeler;
       üyeler["isim"] = to!JSONValue(isim);
       üyeler["numara"] = to!JSONValue(numara);
       üyeler["notlar"] = to!JSONValue(notlar);

       JSONValue json;
       json.object = üyeler;
       json.type = JSON_TYPE.OBJECT;
       return json;
   }
}

JSONValue JSONBelgesi()
{
   JSONValue json;
   json.type = JSON_TYPE.OBJECT;
   return json;
}

void main()
{
   auto öğrenciler = [ Öğrenci("Ayşe", 12, [ 90, 100 ]),
                       Öğrenci("Başak", 34, [ 95, 99 ]) ];

   JSONValue belge = JSONBelgesi();
   belge.object["öğrenciler"] = to!JSONValue(öğrenciler);

   writeln(toJSON(&belge));
}

Çıktısı:
'{"öğrenciler":[{"isim":"Ayşe","numara":12,"notlar":[90,100]},{"isim":"Başak","numara":34,"notlar":[95,99]}]}'

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

May 27, 2012

Ali hocamın başlattığı bu sınıftaki eksiklikleri dile getirmeyi unutmuşum. Aslında eşleme tablosunu belirtilmiş ama denemesem de bunun zor olmadığını ("type detect" dışında) düşünüyorum. Çünkü elimizde bir çok tür için n'apmamız gerektiği var. Sadece bunu sıralı bir düzen içinde yapmamız gerekmekte.

Bir diğer husus ise True/False için boolean değerleri. Bu konuda da zaten elimizde bool diye bir tür var. Sanırım bu da çok zorlamayabilir ama bir de Null varmış! Öyle ya, değerler boş da olabilir...

Sanırım en önemlisi de nesne (object) temelli bir sorun. Bunu yukarıdaki iletiyi yazmadan evvel farketmiştim ki zaten bu başlığı açmamdaki sebep bu. Çünkü bir JSON içerisinde birden fazla struct olabilir. Ali hocamın verdiği örneği (Öğrenci) düşünürsek ana kök nesne (belge) içine { } öğrencileri alıyoruz. Pekala Öğretmen yapısı da olabilir ki bu JSON standartları içinde birbirini etkilemeyen bir husustur. Peki kök nesneyi kapamadan ikinci bir yapıyı nasıl ekleyeceğiz. Gerçi string temelli bunu yapabiliriz. Çünkü sondaki karakteri } silip sonuna ikinci yapıyı ve sildiğimiz güzel parantezini eklememiz yeterli olacakmış.

Düşünüyorum da; bu son söylediğim de zor değilmiş...:)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

May 27, 2012

'{
"erkekler":
[
{"isim":"Ali","numara":12,"notlar":[90,100]},
{"isim":"Behsat","numara":34,"notlar":[95,99]}
],
"kızlar":
[
{"isim":"Ayşe","numara":12,"notlar":[90,100]},
{"isim":"Başak","numara":34,"notlar":[95,99]}
]
}'

Meğer, iki yapıyı birden köke zahmetsizce ekleyebiliyormuşuz. Çünkü 'toJSON()' işlevi içinde 'appender!string()' kullanılıyormuş. Ancak ters ekleniyorlar çünkü kodu şöyleydi:

:    :    :
   JSONValue belge = JSONBelgesi();
   belge.object["kızlar"] = to!JSONValue(kızlar);
   belge.object["erkekler"] = to!JSONValue(erkekler);
   writeln(toJSON(&belge));
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

May 27, 2012

Yöntemi çok incelemedim ama gerçekten de hash ile ilgili bir durummuş. Aslında sırasının bir önemi de yok. Sonuçta biz JSON içinden bir alt kökü çekip alabiliyoruz.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

May 27, 2012

Önce gözüme çarpan bir ayrıntı: unittest bloğunda neden enforce() kullanmışım acaba? Tabii ki assert() olması gerekiyor. (Sonuçta farketmez çünkü testler yine de başarısız olurlar ama kavramsal olarak assert() doğru.)

Alıntı (Salih Dinçer):

>

eşleme tablosunu belirtilmiş ama denemesem de bunun zor olmadığını ("type detect" dışında) düşünüyorum. Çünkü elimizde bir çok tür için n'apmamız gerektiği var. Sadece bunu sıralı bir düzen içinde yapmamız gerekmekte.

Gerçekten çok kolay: Eşleme tabloları da OBJECT düzeninde olmalılar. Zaten Öğrenci yapısı içinde bir örneği var. Türün anlaşılması için de isAssociativeArray!T denetiminden yararlanılabilir.

Alıntı:

>

Bir diğer husus ise True/False için boolean değerleri. Bu konuda da zaten elimizde bool diye bir tür var. Sanırım bu da çok zorlamayabilir ama bir de Null varmış! Öyle ya, değerler boş da olabilir...

Doğru. null denemesi için de (değişken is null) söz dizimini hatırlamak gerek.

Alıntı:

>

Peki kök nesneyi kapamadan ikinci bir yapıyı nasıl ekleyeceğiz.

Her üyeyi to!JSONValue ile işleyince zaten her şey otomatik ve özyinelemeli olarak hallolacak. Çözülmesi gereken sorun, Öğrenci.opCast(T : JSONValue) yüklemesinde olduğu gibi bütün üyeleri elle teker teker işlememek. "Bütün üyelerini işle" diyebilmeliyiz.

JSON'la oynadığımız sıralarda bu soruyu kendim sormuştum ve güzel yanıt almıştım (ama şimdi hatırlamıyorum :)):

http://www.digitalmars.com/d/archives/digitalmars/D/learn/Getting_only_the_data_members_of_a_type_34086.html

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

May 27, 2012

Alıntı (Salih Dinçer):

>

Ancak ters ekleniyorlar

Dün konuştuğumuz gibi, eşleme tablolarında sıra belirsiz. Tek anlayabildiğimiz, "kızlar" ve "erkekler" dizgilerinin hash değerlerinin perde arkasında kullanılan dizi indekslerinin o sırada rast gelmeleri.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

May 27, 2012

Alıntı (Salih Dinçer):

>

Belki yapacağımız çalışmalar ileride bu sınıfın daha çok gelişmesini sağlayabilir. Açıkçası, Phobos kütüphanesi içinde biz Türkler'den bir şey bulunması gurur verici olurdu...:)

Salih sana kesinlikle katılıyorum ve böyle bir konuda her zaman elimden geleni yapmaya hazırım. Eklediğin kodlara baktığım zaman bir sınıftan ziyate güzel bir şekilde Ali tarafından yazılan bir to şablon metodu görüyorum.

Sana katılıyorum bu yapı etrafında kendi işlerimizi görecek güzel bir JSON yönetim sınıfı geliştirebiliriz, hatta belki JSON sınıfına alternatif bir sınıf bile hazırlayabiliriz. Öncelikle bunun bir proje haline getirilmesi amaç, hedef ve görevlerin ortaya konması nelerin nasıl yapılacağı konusunda daha net bir ortam oluşmasını sağlayacaktır diye düşünüyorum.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

May 28, 2012

Alıntı (acehreli):

>

Her üyeyi to!JSONValue ile işleyince zaten her şey otomatik ve özyinelemeli olarak hallolacak. Çözülmesi gereken sorun, Öğrenci.opCast(T : JSONValue) yüklemesinde olduğu gibi bütün üyeleri elle teker teker işlememek. "Bütün üyelerini işle" diyebilmeliyiz.

Sanırım bunu gösterge (pointer) ile yapabiliriz. Örneği 'Öğrenci.opCast()' içindeyken '&this''i ekrana yazarsak ilk elemanın adresini alırmışız. Aynı şekilde şu aşağıdaki verileri de elde edebiliyormuşuz.

       immutable adresKapasitesi = this.sizeof; // 3 size_t için 24
       immutable adresAralığı = size_t.sizeof * 2; // 32 bit'de 8

       writeln("Adres Kapasitesi: ", adresKapasitesi);
       writeln("Adres Aralığı: ", adresAralığı);

Şimdi burada tek sorun 'this'.sizeof'un değişken oluşu. Örneğin numara elemanı byte olsaydı bu değişken bellekte 4 byte kaplayacaktı. Bize öyle bir işlev lazım ki 'this'++'ı yapamıyoruz ama 'bu++' şeklinde kullandığımızda bize sonrakinin adresini versin. Aslında enum ile bunu yapabileceğimizi düşünmekteyim. Biraz kafa yormaca...:)

Alıntı (zafer):

>

...kodlara baktığım zaman bir sınıftan ziyate güzel bir şekilde Ali tarafından yazılan bir to şablon metodu görüyorum.
Ben de yakında bir sınıf görebileceğimizi düşünüyorum. Gayret edersek neden olmasın?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

May 28, 2012

Hocam ben derleyemedim ve şu hatayı aldım:
'
salih@NB:~/d.ders/JSON$ dmd alijsonyeni.d
alijsonyeni.d(203): Error: struct alijsonyeni.İçYapı no size yet for forward reference
alijsonyeni.d(203): Error: struct alijsonyeni.İçYapı no size yet for forward reference
alijsonyeni.d(203): Error: struct alijsonyeni.İçYapı no size yet for forward reference
alijsonyeni.d(203): Error: struct alijsonyeni.İçYapı no size yet for forward reference
'
Not: 203. satırda İçYapı başlıyor...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

May 28, 2012

Şimdi 64 bit ile de derledim ve aynı hatayı aldım. Şu dosyayı dener misiniz?

http://codepad.org/sDG4CJ7K/raw.d

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

« First   ‹ Prev
1 2 3 4 5