March 30, 2012

Ali eline sağlık çok güzel olmuş, bende bir süredir dlang.org forumlarını inceliyordum. Orada da böyle bir örnek var bende onu bir kenara koymuş incelemeyi düşünüyordum ama JSON'a da yabancı olduğum için biraz daha araştırmak ve anlamak için kendime zaman vermiştim.

Bu örnek bir çok konu içeriyor özellikle benim son zamanlarda yakınen ilgilendiğim şablon konusunu, bu kodları iyice incelemek niyetindeyim, tekrar teşekkürler.

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

March 31, 2012

Zafer'in bu başlangıcı ile Ali'nin kattığı çeşniler birleşince ortaya yemede yanında yat çok güzel kodlar çıkmış. Özellikle bu sistem için olmazsa olmaz try-catch cuk oturmuş, yetmemiş enforce ile adeta mühürlemişiz. Eline sağlık Ali ama ben bunu da sadeleştirme niyetindeyim...:)

Şu ifadeler çok hoş...
Alıntı:

>

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.

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

March 31, 2012

Biliyorum...:)

Aşağıdaki kod Ali hocamın örneğinin tamamı değil ve yapmak istediğiniz başka bi'şi. Ancak kendime göre olayı anlamak için basit bir temele oturtmalıydım. Sanırım anladım ama dizge (string) olmayan verileri nasıl işleyebileceğimi bilmiyorum. Yani dikkat ederseniz veri yapısındaki sayısal ifadeleri yine alfasayısala çevirdim.

/*
jsonÖrnek.d (31.03.2012)
*/

import std.stdio, std.json;

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

string veri =
`{
   "belge" : "Öğrenciler Yapısı (struct => JSON)",
   "türü"  : "ham-UTF8",
   "Öğrenciler" : [{
           "isim"   : "Ali",
           "numara" : "12",
           "notlar" : ["90", "100"]
       }, {
           "isim"   : "Ayşe",
           "numara" : "22",
           "notlar" : ["100", "90"]
   }]
}<- Burada veri biter ve geri kalan okunmaz...`;

void main() {
   JSONValue[] json = parseJSON(veri).object["Öğrenciler"].array;

   foreach (i, Öğrenciler; json)
   {
       writefln("%s(%s)'nin notları:", json[i].object["isim"].str,
                                       json[i].object["numara"].str);

       foreach (not; json[i].object["notlar"].array)
       {
           writefln("\t\t\t%s", not.str);
       }
   }
}

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

March 31, 2012

Aman duymasın, huzurlarınızda Jérémie Pelletier (mailto:jermiep@gmail.com)'in kulaklarını çınlatmak istiyorum...

Meğer sayısal değerlerde json[i].object["numara"].integer şeklinde kullanmamız gerekiyormuş.

Tabi bu benim hatam, gidip ilgili belgeleri incelemeliydim; bunu yapmayıp .str yerine .int ve .num gibi şeyler denedim olmadı. İşte bu yüzden kulaklarını çınlatmak istiyorum ya....:)

Çünkü object'i .obj, array'i .arr şeklinde kısaltmayıp bir tek .str diye kısaltma kullanmış. Herhalde rezerve edilen keyword'ler nedeniyle. Bence integer yerine de .num kullanmalı ve tümünü kısaltmalı. Çünkü gerçekten çok uzunlar... :huh:

Dip Not: Ondalıklı sayıları ekrana yansıtmada başarılı olmadım. Onlar için de floating takısını kullanmak gerekiyormuş.

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

March 31, 2012

Ondalıklı sayılarda ilginç bir hata dikkatimi çekti. Ali hocamın kodunu da şimdi deneyeceğim ama aşağıdaki kodu denerseniz Ali'nin notları ".0" ile bitmediği için çok çok çok büyük bir sayı çıkıyor. Bunun sebebini bilen var mı? Gerçi sebep veya çözümden çok böyle bir hatalı veri girişi durumunda bu sayıların üretilmesini engellememiz lazım...:)

/*
sample.d (31.03.2012)
*/
import std.stdio, std.json;

struct Students {
   string name;
   ulong id;
   float[] points;
}

string data =
`{
   "document" : "Structure of Students (struct => JSON)",
   "type"  : "raw-UTF8",
   "Students" : [{
           "name"   : "Ali",
           "id" : 12,
           "points" : [90, 100]
       }, {
           "name"   : "Aliye",
           "id" : 22,
           "points" : [100.31, 90.12]
   }]
}`;

void main() {
   JSONValue[] json = parseJSON(data).object["Students"].array;

   foreach (i, Students; json) {
       writefln("Name is %s(%d) points:", json[i].object["name"].str,
                                          json[i].object["id"].integer);

       foreach (point; json[i].object["points"].array) writefln("\t\t\t%.2f",
                                                              point.floating);
      /*
                **** This problem is only on Linux platform ****
      */
   }
}

Çıktısı:
'Name is Ali(12) points:
11940115323488377087929451065866105745799014338448019690167164459299154807804299564932151734534166
27537385603673906558769651305258572422736227020485825335490978611003774078557010724249945801605319
90575576071596167115801350083654692820961417187136992493635710648866081231248523630408052902020355
17765594475064837997922998241906618127519537233433328035827455630604945148051062049038457749066258
86993095108156964436658137389540363837653001333217007437831122521973339073871488536429737772722611
180186496587978285051
13266794803875974542143834517629006384221127042720021877963516065887949786449221738813501927260184
75041539559637673954188501450287302691929141133873139261656642901115304531730011915833273112894799
89528417857329074573112611204060769801068241319041102770706345165406756923609470700453392113355950
19739549416738708886581109157674020141688374703814808928697172922894383497834513387820508610073620
96658994564618849374064597099489293152947779259130008264256802802192598970968320596033041969691790
200207218431086983390'

Dip Not: Bu ileti, std.json yazarı Jeremi gibi yabancılar için düzenlenmiştir...

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

March 31, 2012

Bende sorunun real türünden kaynaklandığını tespit ettim. Eğer sınıfta iki yerde double şekline çevirince böyle devasa bir sayı üretmiyor; Onun yerine 0.00 yazıyor...

Bu arada kodu göz doldurmasın diye bilerek kısaltmıştım. Önceki sayfada aşağıdakine benzer yapmıştım:
Alıntı:

>
>     JSONValue[] json = parseJSON(veri).obj["Öğrenciler"].arr;
>
>     foreach (i, Öğrenciler; json)
>     {
>         writefln("%s(%d)'nin notları:", json[i].obj["isim"].str,
>                                         json[i].obj["numara"].num);
>
>         foreach (not; json[i].obj["notlar"].arr)
>         {
>             writefln("\t\t\t%.2f", not.flo);
>         }
>     }
> ```

>
Şimdi sınıfın yazarı ile iletişim kuracağım. Önceki sayfada bahsettiğim gibi biraz sadeleştirmeyi düşünüyorum. Bence sınıfı birlikte daha çok geliştirebiliriz. Örneğin sondaki hata atan bölüm (exception sınıfı) iyileştirilebilir. Özellikle hep line=1 değeri dönüyor ve JSON verisinin neresini işaret ettiği anlaşılmıyor. Anladığım kadarıyla kod satırları sayamıyor ya da Linux uyumsuzluğu söz konusu. Bir de Windows'da denemeli.

Hoşça kalın...

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

Alıntı (Salih Dinçer):

>

Eline sağlık Ali ama ben bunu da sadeleştirme niyetindeyim...:)

Alıntı (Salih Dinçer):

>

Meğer sayısal değerlerde json[ i ].object["numara"].integer şeklinde kullanmamız gerekiyormuş.

Alıntı (Salih Dinçer):

>

Onlar için de floating takısını kullanmak gerekiyormuş.

Benimki sade görünmüyorsa o konuları da desteklediği için. ;)

Ali

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

March 31, 2012

Hatayla karşılaştıktan sonra aslında çok şaşırtıcı olmadığı görülüyor. Dikkat edersek dosyadaki bilgilerin hangi düzende olduğu hiçbir yerde belirtilmiyor. JSON okuyucuları bunu yalnızca veriye bakarak anlıyorlar.

Ali'nin notlarının sonunda nokta olmadığı için integer'lar ve o yüzden JSONValue'nun içindeki union'ın long olan üyesine yazılıyor. Biz program içinde '.floating' dediğimizde ise o long değere karşılık gelen bitlerin IEEE kesirli sayı gösterimindeki saçma bir değerle karşılaşıyoruz... diyeceğim, ve doğru... ama writefln()'de de bir hata olmalı çünkü sonuçta yazdırılanlar kesirli sayı olamazlar.

Ali

İlgisiz not: Her ne kadar ben de öz kodları sevsem de küme parantezleri olmayan kodların hatalarını ayıklamak daha zor oluyor. Örneğin sonda foreach şöyle olsa:

       foreach (not; json[i].object["notlar"].array) {
           /* ... hata ayıklarken buraya satırlar ekler ve silerim ... */
           writefln("\t\t\t%.2f", not.floating);
           /* ... buraya da ... */
       }

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

April 02, 2012
JSONValue to(Hedef : JSONValue, T)(T değer)
..

Burada to! şablonunu JSONValue için özelliyoruz ve şablon parametre listesinde Hedef ve T isimli iki parametre görüyorum. Şimdi burada to şablonu JSONValue tipi ile çağrıldığında bu şablon kullanılsın ayrıca böyle bir çağrıda Hedef şablon parametresinide JSONValue tipinde işaretle demiş oluyoruz, doğru mu?

Diğer taraftan Hedef parametresi şablon metodu içinde hiç kullanılmamış, yinede böyle bir tanım yapmak gerekir mi?

static if (isSomeString!T)
..
else static if (is (T : long))
..

static if ile daha önce karşılaşmıştım ama hala tam olarak kavrayamadım. Neden if-else yerine static if kullandık?

isSomeString! şablon metodumuzu daha öncesinden tanıyorduk zaten kendisine geçilen T tipinin bir string tip olup olmadığını test ediyordu. is! şablonunu çok aramama rağmen ne yerini nede tanımını bulamadım, kodlardan anladığım kadarı ile kendisine geçilen ifadeyi kontrol edip true veya false değeri döndürüyor.

Ayrıca yine kodlardan anladığım kadarıyla is! şablonunun tiplere göre özelleşmiş sürümleri mevcut, burada aklıma yine daha önceden tanıdığımız Unqual! geldi. is! şablonu ile kullanmak iyi olmaz mıydı?

else static if (__traits(compiles, cast(JSONValue)değer))

Mümkünse bu satırında daha detaylı bir anlatımını rica ediyorum. Bu arada ben mi yanlış yerlere bakıyorum anlamadım ama ben yine __traits metodunu bulamadım, nerede acaba?

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

April 02, 2012

Alıntı (zafer):

>

Hedef parametresi şablon metodu içinde hiç kullanılmamış, yinede böyle bir tanım yapmak gerekir mi?

Gerekir. Öyle olmasa, to!JSONValue(42) yazıldığında T'nin JSONValue olduğunu belirtiyoruz gibi olur ama öte yandan T parametre listesinde geçtiği için ve bu durunda 42'nin türü olan 'int' olarak da çıkarsandığı için JSONValue ve int birbirlerini tutmazlar.

Belki de o 'to' özellemesi içindeki JSONValue'lar yerine de Hedef yazmalıydık. (?)

Alıntı:

>
> static if (isSomeString!T)
> ...
> else static if (is (T : long))
> ...
> ```

>
> static if ile daha önce karşılaşmıştım ama hala tam olarak kavrayamadım. Neden if-else yerine static if kullandık?

if çalışma zamanında işletilir. Şablonlar ise bütünüyle derleme zamanı olanaklarıdırlar. Bunun nedeni D'nin 'static typing'e sahip bir dil olmasıdır. Derlenen her koddaki herşeyin türü derleme zamanında bellidir. Onun için türlerle ilgili sorgulamaları derleme zamanında işleyen 'static if' ile yapmak gerekiyor.

Alıntı:
> is! şablonunu çok aramama rağmen ne yerini nede tanımını bulamadım, kodlardan anladığım kadarı ile kendisine geçilen ifadeyi kontrol edip true veya false değeri döndürüyor.

Şurada "is ifadesi" başlığı altında ve zamanında tamamen anlamadan yazdığım bir şeyler var:

 http://ddili.org/ders/d/kosullu_derleme.html

(Aslında 'static if' de orada.)

Ama 'is' ifadesinin isSomeString'e tam uyan kullanımını şurada "İsimli kısıtlama yöntemi" başlığı altında anlatıyorum:

 http://ddili.org/ders/d/sablonlar_ayrintili.html

isSomeString de aynı oradaki uçabilir_mi şablonu gibi gerçekleştirilmiştir.

Alıntı:
> Unqual! geldi. is! şablonu ile kullanmak iyi olmaz mıydı?

Anlıyorum. Şu işlemez diyorsun:


immutable j = to!(immutable JSONValue)(students); // derleme hatası



Hedef gibi parametreden çıkarsanmayan türler için bunun en iyi yolunun ne olduğunu bilmiyorum. Örneğin şu da ek olarak tanımlanabilir:


JSONValue to(Target : immutable JSONValue, T)(T value)



Ama kullanıcılar yukarıdaki satırdaki derleme hatasını şöyle de aşabilirler:


immutable j = cast(immutable JSONValue)to!(JSONValue)(students);



Ben bu konuyu (sorunu) İngilizce forumlarda dile getirmiştim. Keşke işlevlerin dönüş türlerinde 'unique' gibi bir anahtar sözcük belirtilebilse, o zaman işlev "bu döndürdüğüm nesneden elimde başka hiç bulundurmuyorum; gerektiğinde immutable olarak da kullanabilirsiniz" demiş olabilir.

O olsaydı o zaman to'nun JSONValue özellemesi immutable bir değişkeni ilklemek için de kullanılabilirdi. Ama öyle bir anahtar sözcük yok. :) Zaten belki başka sıkıntılar da getiriyordur; derinine incelediğimi söyleyemem.

Alıntı:
>
>
>

else static if (__traits(compiles, cast(JSONValue)değer))

>

Mümkünse bu satırında daha detaylı bir anlatımını rica ediyorum. Bu arada ben mi yanlış yerlere bakıyorum anlamadım ama ben yine __traits metodunu bulamadım, nerede acaba?

Genel bir bilgi olarak Google aramalarında "site:ddili.org" eklenebiliyor. Yani şu arama "Tür Nitelikleri" bölümünü buluyor:

'__traits site:ddili.org'

http://ddili.org/ders/d/tur_nitelikleri.html

Digital Mars'ta da şurada:

http://dlang.org/traits.html#TraitsKeyword

Ali

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