Jump to page: 1 2
Thread overview
Ayar yönetim sınıfı
May 23, 2012
zafer
May 24, 2012
Salih Dinçer
May 24, 2012
zafer
May 24, 2012
Salih Dinçer
May 24, 2012
Salih Dinçer
May 24, 2012
Salih Dinçer
May 24, 2012
zafer
May 25, 2012
zafer
May 25, 2012
Salih Dinçer
May 25, 2012
zafer
May 25, 2012
Salih Dinçer
May 25, 2012
Salih Dinçer
May 25, 2012
Salih Dinçer
May 25, 2012
zafer
May 24, 2012

Bu aralar yoğunluktan dolayı Divid projesini askıya almış olsamda hem Divid için hemde genelde kullanmak istediğim bir süredir aklımda olan bir ayar yönetim sınıfı yazmaya yavaş yavaş başladım.

Bu sınıf için C# dilinde kullanılan ConfigurationManager (http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager%28v=vs.80%29) sınıfından esinlendiğimi söylemeliyim. Bildiğim kadarıyla bu sınıfın asıl yaptığı xml tabanlı ve programAdi.config uzantılı bir dosyayı yönetmek ve bunun için yararlı ve kolay olanaklar sunmak. XML dosyası anahtar (key) ve deger (value) çiftlerinden oluşan özel bir yapıda, ConfigurationManager sınıfı sayesinde anahtarları kullanarak değerlere hızlı ve kolay bir şekilde ulaşmak mümkün oluyor.

Ben bu yapının benzerini D için kurmak niyetindeyim. programAdi.config dosyası yerine programAdi.ayar dosyası ve xml mimarisi yerine json kullanmayı hedefliyorum. Anahtar-değer çiftlerini saklamak için eşleme tablolarından faydalanmak niyetindeyim. Daha iyi öneriler varsa onlarada açığım :)

Neyse soruma gelirsem, AyarAnahtar isimli bir niteliğim var ve bir eşleme tablosu döndürüyor ama bu işlemi bir türlü başaramadım. Sınıf ve main metodları şöyle

module AyarYonetici;

public class AyarYonetici
{
	private string[string] ayarTablosu = ["anahtar1": "deger1",
										  "anahtar2": "deger2",
										  "anahtar3": "deger3"];
	public this()
	{
		//
	}

	@property string[string] AyarAnahtari() const
	{
		return ayarTablosu;
	}
}

Bu sınıfı test etmek için kullandığım kodlar şöyle;

import std.stdio;
import AyarYonetici;

void main()
{
	AyarYonetici ayar = new AyarYonetici();

	string deger = ayar.AyarAnahtari["anahtar2"];
	writefln("Anahtar2'nin değeri : %s", deger);

	writeln("Başarıyla Bitti");
}

Derlemeye çalıştığımda şu hatayı alıyorum ;

Alıntı:

>

zafer@debian:~/projeD/AyarModulu$ dmd -w -wi main.d AyarYonetici.d
AyarYonetici.d(15): Error: cannot implicitly convert expression (this.ayarTablosu) of type const(immutable(char)[][string]) to string[string]
zafer@debian:~/projeD/AyarModulu$

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

May 24, 2012

Öncelikle 'string deger = 'ayar.AyarAnahtari['"anahtar2"'];'' satırındaki işlevi sanki eşleme tablosu gibi nasıl böyle kullanmayı düşünüyorsun? Ama sanırım ''writeln('deger['"anahtar2"']');'' şeklinde çalışması gerekir.

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

May 24, 2012

Alıntı (Salih Dinçer):

>

Öncelikle 'string deger = 'ayar.AyarAnahtari['"anahtar2"'];'' satırındaki işlevi sanki eşleme tablosu gibi nasıl böyle kullanmayı düşünüyorsun?

Aslında haklısın sanırım geriye döndürdüğü yapı bir eşleme tablosu, ancak bu bir nitelik (property) olunca nitelik üzerindende eşleme tablosuna ulaşmak mümkün oluyor sanırım. Bunu Ali'den detaylı bir şekilde dinlemeyi çok isterim. Peki ben bunu nasıl yaptım. Şu örneğin çalıştığını görünce cesaretlendim sanırım :)

import std.stdio;

class BirSinif
{
	private int[] birDizi = [10, 11, 12, 13, 14, 15];

	public this()
	{
		//
	}

	@property int[] BirDizi() const
	{
		return birDizi.dup;
	}
}

void main()
{
	BirSinif ornekSinif = new BirSinif();

	int deger = ornekSinif.BirDizi[2];

	writefln("Index 2'nin degeri : %s", deger);
}

Alıntı (Salih Dinçer):

>

Ama sanırım ''writeln('deger['"anahtar2"']');'' şeklinde çalışması gerekir.

O şekilde çalışacağını sanmıyorum neticede deger string bir değişken eşleme tablosu gibi davranmasını beklemek garip olmaz mı?

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

May 24, 2012

Haklısın denedim de çalışıyor ama geliştirme yaparken yanıltıcı olabilir. Özetle, aşağıdaki örnekte koyulaştırdığım kırmızı parantezler olmadan da yazılabiliyormuş:

import std.stdio;

class Bir
{
   private auto birDizi = [0, 1, 2, 3];

   public this() { }

   @property int[] dizi()
   {
       return birDizi.dup;
   }
}

void main()
{
   auto Bir = new Bir();

' 'writeln(Bir.dizi'()'[1]);''

   auto table = ["bir": 1, "iki": 2, "üç": 3];
   auto mirror() { return table.dup; }
   auto value = mirror();

   writeln(value["iki"]);
}

Çıktısı:
'1
2'

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

May 24, 2012

Peki hocam iki soru sormalıyım:
(Zafer sağ olsun, sayesinde çıkıyor bu sorular...)

  1. soru için işaretlen satırda, kopyasını almak gereksiz bir şey değil mi? Çünkü her işlemde kopyası alındığı için bellek müsaade ettiği müddetçe kopyaları oluşur. Üstelik zannedersem işlem yapmıyor gibi görünür.

  2. soru için işaretlediğim satır ise kendini mi çağırıyor yoksa package {} kümesini mi? Normalde Java OOP standartlarına göre öyle gibi görünüyor ama burada sanki gereksiz yere kümeler kullanıyorum değil mi?

module ayarPaketi;
package {
	public class AyarYonetici
	{
	    private string[string] ayarTablosu;

	    public this()
	    {
	        ayarTablosu = ["anahtar1": "deger1",
	                       "anahtar2": "deger2",
	                       "anahtar3": "deger3"];
	        foreach(key, value; ayarTablosu) writeln(key, ": ", value);
	    }

	    @property string[string] AyarAnahtari()
	    {
	        return ayarTablosu.dup; // <-- 1. soru
	    }
	}
}

import std.stdio;
import ayarPaketi; // <-- 2. soru

void main()
{
   AyarYonetici ayar = new AyarYonetici();

   ayar.AyarAnahtari.remove("anahtar1");
   writeln();
   foreach(key, value; ayar.AyarAnahtari) writeln(key, ": ", value);
}

Çıktısı:
'anahtar1: deger1
anahtar2: deger2
anahtar3: deger3

anahtar1: deger1
anahtar2: deger2
anahtar3: deger3'

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

May 24, 2012

Anladım hocam, ama hala package {} kümesi bir miktar kafamı karıştırıyor. Yani sınıfları derleyip toplayan bir şey olsa gerek; ve dışında kalanlar ile iletişimini kesen... (namespace ile karıştırıyor da olabilirim!)

Neyse, bu gereksiz şeyleri denemeyip (en azından faydasını görene kadar) daha yararlıları ile uğraşmalı. Örneğin Zafer'in değişmezlik olayına girersek şu iki şekilde de yapabildiğimizi ama 2'ncisinin sınıfın her yerinde değişmez olduğunu belirtmeden geçemeyeceğim. Muhtemelen bunlar çok gerekli olduğu durumlar olabilir:

Alıntı ((1) Sadece özellikte geçerli olan değişmezlik):

>
> public class AyarYonetici
> {
>     private string[string] ayarTablosu;
>     :    :    :
>     @property const (string[string]) AyarAnahtari() {
>     :    :    :
> ```

>

Alıntı ((2) Her yerde geçerli olan değişmezlik):
>
>
>

public class AyarYonetici
{
private const (string[string]) ayarTablosu;
: : :
@property auto AyarAnahtari() {
: : :

>

Cevaplarınız için teşekkür ederim...

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

May 24, 2012

İki değişiklikle başlayalım:

  1. ayarTablosu üyesinin ilklenmesini kurucu işleve taşıyalım. Yoksa daha sonra "non-constant expression" hatası oluşuyor. (Bu dmd'nin başka bir hatası: eşleme tablolarının hazır değerleriyle (literal) ilgili bilinen sorunlar var. Daha giderilmediler.)

  2. AyarAnahtari() işlevinin sonundaki const'ı kaldıralım. Her ne kadar Zafer eşleme tablosunu korumak istemişse de sorun bununla ilgili. O yüzden önce 'const' olmadığında ne olduğuna bakalım:

public class AyarYonetici
{
   private string[string] ayarTablosu;

   public this()
   {
       ayarTablosu = ["anahtar1": "deger1",
                      "anahtar2": "deger2",
                      "anahtar3": "deger3"];
   }

   @property string[string] AyarAnahtari()
   {
       return ayarTablosu;
   }
}

import std.stdio;

void main()
{
   AyarYonetici ayar = new AyarYonetici();

   ayar.AyarAnahtari.remove("anahtar1");      // <--

   // string deger = ayar.AyarAnahtari["anahtar2"];
   // writefln("Anahtar2'nin değeri : %s", deger);

   writeln(ayar.AyarAnahtari);
}

Evet, 'const' olmadığı zaman üyeden örneğin eleman çıkartabildik. Çıktısı:

["anahtar2":"deger2", "anahtar3":"deger3"]

O yüzden üye işlevi Zafer'in yaptığı gibi 'const' olarak işaretlemek gerek. Öyle yapınca nesneyi bu işlev içinde değiştirmeyeceğimizi söylemiş oluyoruz. Ama döndürdüğümüz referansı unutuyoruz. Dönüş türünün de 'const' olması gerek:

   @property const(string[string]) AyarAnahtari() const

Zafer'in kodu şimdi derleniyor.

Ali

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

May 24, 2012

Alıntı (Salih Dinçer):

>
  1. soru için işaretlen satırda, kopyasını almak gereksiz bir şey değil mi?

Bence de öyle.

Alıntı:

>
  1. soru için işaretlediğim satır ise kendini mi çağırıyor yoksa package {} kümesini mi?

Onu anlayamadım. :( O satırda hiçbir şey çağrılmıyor, ayarPaketi modülünün olanakları burada kullanılabilir hale geliyor. package'in etkisi de "yalnızca bu klasördeki modüller bunları kullanabilir" demek.

Ali

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

May 24, 2012

Ali öncelikle çok teşekkürler, "non-constant expression" hatasına bende bir anlam verememiştim, umarım dmd bu hatayı bir an önce giderir. Diğer taraftan ilklendirmeyi kurucu işlevde yapmak hem daha okunaklı hemde daha temiz bir kodlama oluşturmuş. Bir elin nesi var iki elin sesi var atasözünü burada bir daha gündeme getirmek isterim :)

Salih, package{} konusunu bende tam olarak kavrayamadım ve kafamda hala isim alanları (namespace) ile karışık bir durumda duruyor. Bir ara bende detaylı bir şekilde bu konuyu incelemek istiyorum. Şu yoğunluk geçtikten sonra artık, o zaman birlikte bakarız belki.

Bu arada const örnekleri güzel olmuş. Ayrıca enson Ali'nin verdiği enum örneği beni şaşırttı. Eşleme tablosu gibi kullanabiliyormuyuz o enum mu?

Alıntı (Salih Dinçer):

>

Öncelikle string deger = ayar.AyarAnahtari["anahtar2"]; satırındaki işlevi sanki eşleme tablosu gibi nasıl böyle kullanmayı düşünüyorsun?

Ali bu konuda diyeceğin bir şeyler varsa, müsait bir zamanında eklersen severek okurum :-D

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

May 25, 2012

Nihayet AyarYönetici sınıfı ile ayar bilgilerini okumayı başardım. Aslında böyle bir sınıf geliştirmek ilk bakışta karışık ve zor gibi görünmesine rağmen işin içine girince ve özellikle Salih ve Ali'nin güçlü desteği sayesinde bu işin çok zor olmadığına kanaat getirdim.

Ancak itiraf etmeliyim ki eşleme tablosunu çalışma zamanında doldurmak beni oldukça zorladı. add, append, insert gibi metotların bir karşılığını bulamadım. Aklımada başka bir şey gelmedi, diğer denemeler ise sonuçsuz kaldı. Neyse ki internet araştırmalarım sırasında rasladığım S-Lang dilinin (http://www.jedsoft.org/slang/doc/html/slang-12.html) dökümanlarını incelerken karşılaştığım örnek bir anda tüm parçaların yerine oturmasını sağladı ve olay çözüldü. Ancak Ali'den ricam eşleme tablosu konusuna, çalışma zamanında anahtar-değer ekleme işlemininde eklenmesi olacaktır.

İlgilenenler için son duruma ait kodları aşağı ekliyorum. Projeyi denemek isteyenler için önce json dosyaını, sonra sınıfı ve test kodunu ekliyorum.

Alıntı:

>

// test.conf
{
"programAyarlari":[
{"anahtar" : "top" , "deger" : "10"},
{"anahtar" : "left" , "deger" : "10"},
{"anahtar" : "width" , "deger" : "300"},
{"anahtar" : "height" , "deger" : "400"}
]
}

module AyarYonetici;

import std.conv;
import std.file;
import std.json;

public class AyarYonetici
{
	private string[string] ayarTablosu;
	private string ayarDosyasi;

	public this(string ayarDosyasi)
	{
		this.ayarDosyasi = ayarDosyasi;

		AyarDosyasindanOku();
	}

	private void AyarDosyasindanOku()
	{
		string ayarBilgisi = to!string(read(ayarDosyasi));

		JSONValue[string] ayarListesi = parseJSON(ayarBilgisi).object;

		JSONValue[] programAyarlari = ayarListesi["programAyarlari"].array;

		foreach (ayarlar; programAyarlari)
		{
			JSONValue[string] ayar = ayarlar.object;

			EslemeTablosunaEkle(ayar["anahtar"].str, ayar["deger"].str);
		}
	}

	private void EslemeTablosunaEkle(string anahtar, string deger)
	{
		ayarTablosu[anahtar] = deger;
	}

	@property const(string[string]) AyarAnahtari() const
	{
		return ayarTablosu;
	}
}
import std.stdio;
import AyarYonetici;

void main()
{
	AyarYonetici ayar = new AyarYonetici("test.conf");

	string top = ayar.AyarAnahtari["top"];
	string left = ayar.AyarAnahtari["left"];

	writefln("top: %s, left: %s", top, left);

	writeln("Başarıyla Bitti");
}

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

« First   ‹ Prev
1 2