January 30, 2012

Düzeliyorum...:)

Şu şekilde istediğim değeri sınıf içinde de verebildim! Yahu ben D'yi çok sevdim:

import std.stdio, std.cstream, std.md5;
class bellek {
	const int on = 10;
	static uint yedi = 7;
	static ubyte[] veri;

	this(int i=on) {
		veri = new ubyte[i*yedi];
	}
}
void main () {
	auto d = new bellek(16777214);

	//writef ("%d ", d.veri.length);/*
	writefln ("[%s]", getDigestString(d.veri));//*/
}

Henüz D'nin dünyasına girmemiş olanlar için ekrana yazılan iki satırın görüntüsü de şu şekildedir:

salih@DB-N150-N210-N220:~$ ./bel
117440498 [4CE33F8646C98240603D723E9FEE3FA6]

'(d'yi bellek sınıfına varsayılan değerleriyle tanımlayınca da aşağıdaki gibi bir sonuç alıyorsunuz...)'

70 [3287282FA1A1523A294FB018E3679872]

Ne diyelim C'ye kapak olsun, maşaallah...:)

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

January 30, 2012

Çok teşekkürler, bunlar değerli bilgiler. Tabi tüm değişkenler derleme zamanı birbirine oturduğundan (-bknz. aşağıdaki örnek) teorik olarak bir esprisi yok gibi. Ama duruma göre faydaları tartışmasız!

..
d[1].veri = new ubyte[16777214*mat.on];
d[2].veri = new ubyte[mat.karesi(mat.yedi)]; //<--- bunun yerine ubyte[49] veri; yazmak yeterli, komik değil mi...:)
..

Bu örneği iki önceki iletimde vermiştim. İkinci satırdaki çok gereksiz dolambaçlı bir değeri oradan alıp dolaştırıyor; yoksa 49 yazmak bile yeterli! Elbette bu bir deneme çünkü 'mat.veri' dizisi static olduğu için 1. ve 2. kopyası aynı.

Peki ya static olmaz ise niye "Parçalama arızası" verir? Örneğin şurada statik olmayan sınıf elemanlarına hiç bir şekilde ulaşamıyorum:

class bellek {
	int d;
	static int s;
}
static void main () {
	auto b = new bellek [2];
	b[1].s=1;
	writefln ("static bellek'in 1. elemanı: %d", b[0].s);
	writefln ("static bellek'in 2. elemanı: %d", b[1].s);
}

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

January 30, 2012

D'de bütün değişkenler ilklenirler (her tür kendi .init değeriyle):

class C
{
   int i;

   this()
   {
       assert(i == i.init);     // <-- zaten 0 ile ilklenmiş
   }
}

Yukarıda this()'e girildiğinde i zaten int.init ile ilklenmiştir (i.init ile int.init aynı ve çoğu tür için 0). Ama eğer i'nin 10 gibi özel bir değer olması gerekiyorsa onun önceden 0 ile ilklenmesi saçma olur. Üye tanımında bizim belirlediğimi ilk değer, derleyicinin ilkleme adımını ortadan kaldırır:

class C
{
   int i = 10;

   this()
   {
       assert(i == 10);         // <-- özel değerle ilklenmiş
   }
}

Üye tanımındaki değerlerin derleme zamanında bilinmeleri gerekiyor. Ama D'nin derleme zamanında kod işletebiliyor olması çok yararlı:

import std.exception;

string foo()
{
   return "merhaba";
}

string bar()
{
   return "dünya";
}

string selam()
{
   return foo() ~ ' ' ~ bar();
}

class C
{
   int i = selam().length;       // <-- derleme zamanında işletilir
}

void main()
{
   auto c = new C;
}

Tabii onun için bütün işlevlerin gerçekten de derleme zamanında işletilebiliyor olmaları gerekir. Örneğin girişten bilgi alınamaz! :-p (Başka kısıtlamalar da var.)

Ali

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

January 30, 2012

Ali zaten çok güzel bir açıklama eklemiş ancak ben Salih'in kodunu aşağıdaki şekle getirip çalıştırınca sorunsuz çalıştığını gördüm. Tabi bu durumda benimde aklımda bazı sorular oluştu, önce kodu görelim;

import std.stdio;

class bellek
{
   int d;
   static int s;
}

void main ()
{
	bellek[3] b = new bellek();

	b[0].s = 0;
	b[0].d = 1;

	b[1].s = 2;
	b[1].d = 3;

	b[2].s = 4;
	b[2].d = 5;

	writefln ("static bellek'in 1. elemani: %d", b[0].s);
   writefln ("static bellek'in 2. elemani: %d", b[0].d);


	writefln ("static bellek'in 1. elemani: %d", b[1].s);
   writefln ("static bellek'in 2. elemani: %d", b[1].d);


	writefln ("static bellek'in 1. elemani: %d", b[2].s);
   writefln ("static bellek'in 2. elemani: %d", b[2].d);


	/*
   auto b = new bellek [2];
   b[1].s=1;

	writefln ("static bellek'in 1. elemanı: %d", b[0].s);
   writefln ("static bellek'in 2. elemanı: %d", b[1].s);
	 */
}

Alıntı:

>

static bellek'in 1. elemani: 4
static bellek'in 2. elemani: 5
static bellek'in 1. elemani: 4
static bellek'in 2. elemani: 5
static bellek'in 1. elemani: 4
static bellek'in 2. elemani: 5

Kod üzerinde de görüleceği üzere önce "b" isimli bir sınıf değişkeni tanımladım ama bu değişkeni bir dizi olarak tanımladım. Bu esnada 3 elemanlı bir dizi tanımlıyorum ama bunlara sadece bir sınıf kurup onu atıyorum. Doğal olarak dizideki tüm elemanlar aynı nesneyi refere ediyor. Zaten bunu aşağıdaki çıktıda görmek mümkün şeklinde bir açıklama getiriyorum, katılır mısınız?

Diğer taraftan sınıfda bulunan "d" üye değişkenine ulaşmayı beklemiyordum ama gördüğünüz üzere değer atayıp okumayı başardım. Bu konuda asıl bir açıklama yapılabilir?

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

January 31, 2012

Alıntı (zafer):

>
> ...
> bellek[2] b = new bellek();
> ...
> 	b[1].s = 2;
> 	b[1].d = 3;
> ...
> 	writefln ("dinamic bellek'in 1. elemani: %d", b[0].d);
> 	writefln ("dinamic bellek'in 2. elemani: %d", b[1].d);
> din.readLine();
> 	writefln ("static bellek'in 1. elemanı: %d", b[0].s);
> 	writefln ("static bellek'in 2. elemanı: %d", b[1].s);
> }
> ```

>
> Alıntı:
> > dinamic bellek'in 1. elemani: 3
> > dinamic bellek'in 2. elemani: 3
> >
> > static bellek'in 1. elemanı: 2
> > static bellek'in 2. elemanı: 2
>
> Kod üzerinde de görüleceği üzere önce "b" isimli bir sınıf değişkeni tanımladım ama bu değişkeni bir dizi olarak tanımladım. Bu esnada 3 elemanlı bir dizi tanımlıyorum ama bunlara sadece bir sınıf kurup onu atıyorum. Doğal olarak dizideki tüm elemanlar aynı nesneyi refere ediyor. Zaten bunu aşağıdaki çıktıda görmek mümkün şeklinde bir açıklama getiriyorum, katılır mısınız?
Katılıyorum ve çok güzel...:)

Ayrıca katkı sağladığın için ayrıca teşekkür ederim. Benim şu an denediklerim çok gereksiz şeyler. Sadece dilin sınırlarında dolaşmaya ve çoğu zaman kural dışı davranmaya gayret ediyorum. Amacım yeni şeyler keşfetmek...

Yazdığın kodu yukarıda alıntıladığım şekilde değiştirdim. Amacım static'in bir farkının olup olmadığını görmek. Çıktı görüntüsünden anlayacağınız üzere (d)inamic değişkeni ile (s)tatic değişkeni arasında hiç bir fark yok. Çünkü değişkenler ilklendiği için 0 olmaları gerekirken ve sadece 2. elemana (b[1]...) erişim sağlanırken 1. eleman da değişmekte. Özetle; bu şekilde kullanımlarda static kullanmanın bir esprisi yokmuş.

Sevgiler, saygılar...

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

Alıntı (Salih Dinçer):

>

Peki ya static olmaz ise niye "Parçalama arızası" verir? Örneğin şurada statik olmayan sınıf elemanlarına hiç bir şekilde ulaşamıyorum:

> class bellek {
> 	int d;
> 	static int s;
> }
> void main () {
> 	auto b = new bellek [2];
> 	b[1].s=1;
> 	writefln ("static bellek'in 1. elemanı: %d", b[0].s);
> 	writefln ("static bellek'in 2. elemanı: %d", b[1].s);
> }
> ```

>

Hatırlatmak için, ve başka arkadaşlar denemedilerse diye, static üyeler bütün tür için tek oluyorlar; static olmayan üyeler ise her nesne için ayrı oluyorlar. Yani yukarıdaki bellek.s yalnızca bir adet ama bellek.d her nesne için farklı.

Yukarıdaki programı işlettiğimizde şunu görüyoruz:

'static bellek'in 1. elemanı: 1
static bellek'in 2. elemanı: 1
'

İki elemanın s üyeleri de aynı olduğu için ikisi de aynı. O üyeyi b[1].s diye ilklemek yerine sınıfın 'static this' işlevi de kullanılabilir. 'static this' her tür için yalnızca bir kere işletilir ve en azından o türün static üyelerini ilklemek için mantıklıdır:


class bellek {
int d;
static int s;

static this()
{
s = 42;
}
}



Yukarıdaki kod sabit bir değer kullandığı için s aslında tanım satırında da ilklenebilir:


class bellek {
int d;
static int s = 42;
}



Ama tabii 'static this' bambaşka kodlar da işletilebildiği için duruma göre yeğlenir.

static olmayan üyeler konusunu sona bıraktım. :) b[0].d deyince hata olmasının nedeni, D'de sınıfların *referans türü* olmaları. b[0] ve b[1] C'deki NULL göstergelerinin eşdeğeri durumundalar. Gerektiğinde şöyle denetlenebilir:


   if (b[0] is null)


class nesnelerinin new ile oluşturulmaları gerekir. struct'ta durum öyle değil, çünkü onlar değer türleri. C ve C++'tan gelenler (ben dahil! :)) referans türlerine yabancı olabilirler. Java ve C#'tan gelenler zaten biliyor olmalılar. Bununla ilgili şöyle bir şey var:

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

Ayrıca bu sorunun dizilerle ilgisi olmadığını da belirtmek gerek, yoksa şu da aynı hataya sahip:


bellek b;
writeln(b.d);



Daha da ayrıca, :) main'in başındaki 'static'i hiç görmemiştim. Etkisi olduğunu sanmıyorum.

Son olarak, eğer bütün dizi baştan oluşturulması gerekmiyorsa diziyi hep sonuna ekleyerek de oluşturabilirsin:


import std.stdio;
import std.string;

class bellek {
int d;
static int s;

this(int d) {
this.d = d;
}

override string toString() const
{
return format("%s", d);
}
}

void main () {

bellek[] dizi;

foreach (i; 0 .. 10) {
dizi ~= new bellek(i);
}

writeln(dizi);
}



Ali

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

Alıntı (acehreli):

>

Üç tane referans da new ile oluşturulmuş olan tek nesneye erişim sağlamaktalar. new ile oluşturulmuş olan nesnenin d üyesi de oluşturulmuş olduğundan hepsi o d'ye eriştiriyorlar.

Ali o kısmı anladım ama benim anlamadığım daha öncesinde sınıf tanımını şu şekilde değiştirdiğim halde değişkenlere ulaşabiliyor olmam.

class bellek
{
	private:
		int d;
		static int s;
}

Bu tanımdan da görüleceği üzere amacım sınıf değişkenlerini dış dünyaya kapatmak (Sarma) ama buna rağmen main içinden hala bunlara erişebiliyorum. Benim anlamadığım kısım burası, ne dersin?

Alıntı:

>

Ayrıca katkı sağladığın için ayrıca teşekkür ederim. Benim şu an denediklerim çok gereksiz şeyler. Sadece dilin sınırlarında dolaşmaya ve çoğu zaman kural dışı davranmaya gayret ediyorum. Amacım yeni şeyler keşfetmek...

Rica ederim Salih, amacımız burada kodlarken keyif aldığımız bir dil olan D üzerinde hep beraber bilgi paylaşmak, bu sıcak ve samimi ortamı doğrusu çok seviyorum. Bu arada sende aramıza hoşgeldin. Umarım güzel projelerde birlikte çalışma imkanıda buluruz.

Yeni şeyler keşfetmek güzel tabi ama D'nin esnek sınırları sanırım bazen karışıklıklara yol açıyor. Örneğin C# derleyicisi aşağıdaki kodu baştan kabul etmiyor.

Alıntı:

>

bellek[3] b = new bellek();

Bir sınıf değişkeninin bir dizi gibi kullanılmayacağını söyleyerek bize izin vermiyor, belki bu konuda D'de bize kızmalıydı ama belkide bir sistem dili olması ve programcısına güvenen esnek yapısı olayı bu şekle sokuyor olabilir.

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

January 31, 2012

Alıntı (zafer):

>

Alıntı (acehreli):

>

Üç tane referans da new ile oluşturulmuş olan tek nesneye erişim sağlamaktalar. new ile oluşturulmuş olan nesnenin d üyesi de oluşturulmuş olduğundan hepsi o d'ye eriştiriyorlar.

Ali o kısmı anladım ama benim anlamadığım daha öncesinde sınıf tanımını şu şekilde değiştirdiğim halde değişkenlere ulaşabiliyor olmam.

> class bellek
> {
> 	private:
> 		int d;
> 		static int s;
> }
> ```

>
> Bu tanımdan da görüleceği üzere amacım sınıf değişkenlerini dış dünyaya kapatmak (Sarma) ama buna rağmen main içinden hala bunlara erişebiliyorum. Benim anlamadığım kısım burası, ne dersin?
>

Yalnız şöyle bir şey D'nin özel veri erişimi ile C++'ninki farklı. Eğer bu kod C++ kodu olmuş olsaydı dediğin geçerli olurdu. Ama D için 'private' olarak belirlenmiş değişkenlere aynı dosya içinde her yerden erişebilirsin.

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

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

Alıntı (zafer):

>

Bu esnada 3 elemanlı bir dizi tanımlıyorum ama bunlara sadece bir sınıf kurup onu atıyorum. Doğal olarak dizideki tüm elemanlar aynı nesneyi refere ediyor. Zaten bunu aşağıdaki çıktıda görmek mümkün şeklinde bir açıklama getiriyorum, katılır mısınız?

Tamamen doğru. :)

Alıntı:

>

Diğer taraftan sınıfda bulunan "d" üye değişkenine ulaşmayı beklemiyordum ama gördüğünüz üzere değer atayıp okumayı başardım.

Üç tane referans da new ile oluşturulmuş olan tek nesneye erişim sağlamaktalar. new ile oluşturulmuş olan nesnenin d üyesi de oluşturulmuş olduğundan hepsi o d'ye eriştiriyorlar.

Ali

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

January 31, 2012

Alıntı (zafer):

>

Yeni şeyler keşfetmek güzel tabi ama D'nin esnek sınırları sanırım bazen karışıklıklara yol açıyor. Örneğin C# derleyicisi aşağıdaki kodu baştan kabul etmiyor: bellek[3] b = new bellek();

Haklısın, C#'da, statik değişkene hiç bir şekilde erişemedim bile. Belki yanlış bir şeyler yapıyorumdur ama dinamik veriyi değiştirip ekrana olması gerektiği gibi yansıtabiliyorum. Statik ile ilgili satırlarda ise şu hatayı veriyor:

Alıntı:

>

/home/salih/Projects/bellek/bellek/Main.cs(27,27): Error CS0176: Static member `Application.bellek.s' cannot be accessed with an instance reference, qualify it with a type name instead (CS0176) (bellek)

Private ise tıpkı diğerleri gibi davranıyor. Aslında ben eski Pascal'cılardanım. OOP konusuna çok yabancıyım. Bu kadar anahtar sözcük benim çok kafamı karıştırıyor ki bu D'de sanki çok (is, in, out, this, body, ref, pure, nothrow, throw, final switch vb.) var. D'nin hedefleri arasında basitlik de var ama sizce, en az diğer diller kadar karmaşıklaşmaya başlamıyor mu?

Başarılar...

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