July 09, 2012

Bence önce aralıklar için özelleşmiş şu malum üç işlevi, D.ershane'den referansla hatırlayalım...

Aşağıda foreach'in 'for()' işleviyle ifade edilmiş hali bulunuyor ve Ali hocam şurada (http://ddili.org/ders/d/foreach_opapply.html) konuyu çok güzel açıklamış; alıntılayım:
Alıntı:

>

'
'for' '(' ; /* 'bitmediği sürece' /; / 'başından daralt' */') {'

    'auto' 'eleman =' /* 'aralığın başındaki' */;

    // ... ifadeler ...
'}'

'
foreach'in kendi türlerimizle de çalışabilmesi için yukarıdaki üç özel bölümde kullanılacak olan üç özel üye işlev tanımlamak gerekir. Bu üç işlev; 'döngünün sonunu belirlemek', 'sonrakine geçmek (aralığı baş tarafından daraltmak)', ve 'en baştakine erişim' sağlamak için kullanılır.

Bu üç üye işlevin isimleri sırasıyla 'empty', 'popFront', ve 'front''tur. Derleyicinin arka planda ürettiği kod bu üye işlevleri kullanır:

>     for ( ; !aralık.empty(); aralık.popFront()) {
>
>         auto eleman = aralık.front();
>
>         // ... ifadeler ...
>     }
> ```

>
Görüleceği üzere bir döngü olma şartıyla biz bu işlevleri farklı şekillerde kullanabiliriz. Sanırım benim önceki sayfalarda while kullanmam da kuralı bozmuyor? Hatta 'retro()' işlevini kullanmadan şu şekilde de tersini alabilirdik:

void main() {
auto birAralık = Aralık(3, 7);

foreach (eleman; birAralık) eleman.write("\t");
writeln; // Düzden aralığı ekrana yansıttık...

for ( ; !birAralık.empty(); birAralık.popBack()) {

   auto eleman = birAralık.back();

   eleman.write("\t");

}
writeln; // Tersten aralığı ekrana yansıttık...
}

struct Aralık {
: : : // Tabi ek olarak aşağıdakileri de eklediğimizi farzetmeli...
void popBack() {
--son;
}
int back() const {
return son - 1;
}
}



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

Alıntı (zafer):

>

empty()'nin sadece bu gerçeklemede kullanılması gerektigini ve dışarıdan kontrolsüz erişime kapalı olması gerektigini düşünüyorum.

Eğer InputRange ise o üç işlevi sunmuş olması gerekir. İsteyen istediği gibi kullanabilmeli.

"Bu gerçeklemede kullanılması" derken nasıl bir kısıtlama düşünüyorsun? "empty()'yi çağırabilirsiniz ama hemen sonrasında front()'u da çağırmalısınız" gibi bir istek mantıklı değil.

Ayrıca empty()'nin kontrolsüz kullanılacağı da aklıma yatmıyor. Yaptığı tek şey boş olup olmadığını söylemek olduğu için zararlı da olamaz.

Ali

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

July 09, 2012

Alıntı (zafer):

>

birisi yanlışlıkla popFront()' u çagırıp aralıgı daraltma gibi bir durum olabilir mi?

Eğer bu türü bir aralık olarak ilan etmişsek yanlış da kullanılabilir çünkü söylediğin başka her işlev için de geçerli. Herkes her işlevi yanlışlıkla çağırabilir.

Alıntı:

>

Ben bir sınıf yazarı olarak bu metotları kendime saklama hakkına sahipmiyim?

Türün kendisini aralık yapmak yerine bir yan tür tanımlayabilir ve bu türü kendi modülünde tanımlayabilirsin. Tam eşdeğeri olmasa da aşağıdaki sayfada "ÖğrenciAralığı" geçen paragrafta bunun bir benzerini uyguluyorum:

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

Ali

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

July 09, 2012

Alıntı (acehreli):

>

Herkes her işlevi yanlışlıkla çağırabilir.

Herkes her değişkeni yanlışlıkla değiştirebilir. Bunun için değişkenlerimizi immutable ile koruma altını alıyoruz.

Sınıfların ne olup olmadıgı ile ilgili anlatılan yazılırda bazen cd-rom örneği ile karşılaşırız. Burada cd-rom bir sınıfa benzetilir, cd-rom cd okuma işlevini gerçekleştiren kapalı bir kutudur. Dış dünyaya ise sadece kutunun kapağını açıp kapatabileceğimiz bir özelligini açmıştır. Bu sayede cd-rom kapalı kutu içinde tutarlı bir şekilde çalışmakta ve üreticinin öngöremediği dış etkilerden korunmaktadır. Kullanıcı içini açıp kurcalayabilir ama o zaman garanti dışı kalacagını kabul etmiş olur ;)

Alıntı (Salih Dinçer):

>

Sanırım benim önceki sayfalarda while kullanmam da kuralı bozmuyor?

Salih sorun senin while ile kullanman degil. Biz yukarıda bahsettigim cd-rom cihazına ses cd'lerini okuma özelligi ekliyoruz ama gel bu sefer kapağı kapatma imkanımız olmuyor. Kapağı açık bir şekilde satışa sunuyoruz. Yada kapağı kapatıyoruz ama bu sefer aynı özelliği sağlamak için yanında küçük bir kutu ile satışı çıkarmak zorunda kalıyoruz. :)

Benim anladığım olay bu şekilde yanlış anladıysam affola. Neticede bana göre aralık entegrasyonu sınıfta bir erişim zafiyeti yaratıyor ve bence bu önemli bir detay. Tabi diğer taraftan sizin aklınızdan geçen benimde aklımdan geçiyor. Bizden çok daha bilgili olan insanlar bu durumu düşünmedi mi? Oturup konuşmak anlamak gerek tabi ;)

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

July 10, 2012

Eğer gerçekten ihtiyaç varsa aklıma şöyle bir çözüm geliyor;
Şimdi biz aralıkları, bazı işlevleri kullanabilmek için oluşturuyoruz.Eğer aralık işlevlerini uygun şekilde sarma uygularsak ve aralık işlevlerinden gerekenlerini kendi sınıfımız içinde gerçeklersek sorun kalmaz gibi geliyor. Örneğin empty, front ve popFront() bize bir InputRange sunar. foreach() kullanmamız gereken yerde tekTekEriştir() gibi bir işlev tanımlarsak ve foreach()'ı o işlev içinde sunarsak, empty, front ve popFront()'u private ile işaretleyebiliriz. Bu sayede dışarıdan erişime kapanmış olurlar.Tabi gereken her işlev için bir tanımlama yaparsak biraz uzun olabilir.
Bunun dışında eğer çok önemli verilerle çalışıyorsak ben her zaman yedekli çalışılması gerektiğini düşünüyorum. Mesela programın iki çalışması arasında yedek dosyalar(İşimize göre veritabanı vb.) oluşturursak yapılan hataları geri alma şansımız olabilir.

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

July 10, 2012

Alıntı (acehreli):

>

Kesinlikle hayır. Çünkü bunun aralıklarla değil, üyelere erişimle ilgisi var.

Kesinlikle evet. Çünku empty(), popFront(), front() üye metotları temelde sınıfın aralık işlemlerini gerçekleştirmek için varlar. Aksi takdirde bu metotlar sınıfta tanımlanmayacağı için herhangi bir erişim sorunuda yaşanmayacaktır.

Sorunu doğru ortaya koymak gerkir. Bana göde aralıklar "Sınıf üyelerine erişimi kısıtlama" ilkesini bozduğu için bir sıkıntı yaratır. Bu çok önemli mi bilmiyorum, aslında bu dışarıyı kapatılamayan bu metotların içerisinde ne olduğu ile ilgili, örnegin empty() metodu için böyle bir sıkıntıdan söz etmek pek doğru olmaz. Neticede bunu konuşmak gerekir belki mantıklı ve kabul edilebilir bir açıklamasıda olabilir. Ancak bu şekilde bir yaklaşımla degil tabi :)

Alıntı (acehreli):

>

Herhalde bir dilimin elemanlarına erişebilmek de yanlış kabul edilmez:

Ali konuyu saptırıyorsun. Sende biliyorsun ki dilim ve sınıf farklı yapılar ama eğer sen bunları aynı kefeye koyup yorum yapıyorsan, sana diyecek birşeyim yok. Bana sadece haklısın demek kalıyor, istedigin buysa.

   dilim[indeks] = 42;    // cd'nin kutusunu deldik!

Yukarıdada belirttim eğer sen kutuyu bilinçli olarak açıyorsan bu durumda cihazın garanti dışı kaldığınıda kabul etmiş olursun. Buna yapabilecek bir şey yok zaten, benim anlatmak istedigim kasıtlı olmayan durumlardı. Tıpkı hiç kimsenin bilinçli olarak hatalı kod yazmayacagı gibi ;)

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

July 09, 2012

Alıntı (zafer):

>

Neticede bana göre aralık entegrasyonu sınıfta bir erişim zafiyeti yaratıyor ve bence bu önemli bir detay.

Kesinlikle hayır. Çünkü bunun aralıklarla değil, üyelere erişimle ilgisi var.

Ama bazı türler neredeyse bütünüyle erişim sağlamak için vardırlar. Herhalde bir dilimin elemanlarına erişebilmek de yanlış kabul edilmez:

   dilim[indeks] = 42;    // cd'nin kutusunu deldik!

Ama hayır, hiç de kutuyu delmiyoruz çünkü o erişim bile opIndex()'ten (ve arkadaşlarından) geçiyor. Zaten dilim o yüzden yanlış indeks ile erişimleri yakalayabiliyor.

Aynısı aralıklar için de geçerli: Bütün erişim işlevler yoluyla sağlandığı için ne kadar erişim sunduğu aralığın kendisine bağlı. Eğer erişim sağlaması gerekmeyen bir türse zaten aralık arayüzü vermemeli.

Daha önce söylediğin gibi, kendi iç işleri için aralıklardan yararlanabilir ve bunu dışarıya açmayabilir.

Ali

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

July 10, 2012

Alıntı (zafer):

>

bu metotlar sınıfta tanımlanmayacağı için herhangi bir erişim sorunuda yaşanmayacaktır.

Benim söylediğim her şey sınıfın sunduğu elemanlara erişimin gerekli olduğu varsayımına dayanıyor. Yani erişim gerekmişse aralık olarak kodlayabiliriz, erişim gerekmemişse aralık olarak kodlamayabiliriz.

Sen genelde aralıkların sarmayı deldiğini söylüyorsun. Ben buna katılmıyorum çünkü tanım gereği, aralık kullanılmışsa zaten elimizde bir topluluk vardır.

Alıntı:

>

Sorunu doğru ortaya koymak gerkir. Bana göde aralıklar "Sınıf üyelerine erişimi kısıtlama" ilkesini bozduğu için bir sıkıntı yaratır.

Kabul: Eğer erişimi kısıtlanacak bir sınıfsa tabii ki aralıklarla erişim sunulmaz. Tekrar etmek gerekirse, bunun aralıklarla ilgisi yok; sunulmaması gereken erişimi sunmakla ilgisi var.

Alıntı:

>

Alıntı (acehreli):

>

Herhalde bir dilimin elemanlarına erişebilmek de yanlış kabul edilmez:

Ali konuyu saptırıyorsun. Sende biliyorsun ki dilim ve sınıf farklı yapılar

Aynı D dilimleri gibi işleyen bir sınıf yazıldığını düşünelim. Yani tek amacı dizi elemanlarına kontrollü erişim sağlamak olsun. (Zaten D dilimlerinin Phobos türleri olacakları konusunda planlar vardı.)

Bu durumda dilimlerle bu sınıf arasında fark var mıdır? Yok ise, dilimlerde çok yararlı olan aralık arayüzü onunla aynı biçimde işleyen sınıf için zararlı mıdır?

Tek söylediğim, aralıkların kategori olarak sarmayla ilgili sorunları bulunmuyor.

Alıntı:

>
>     dilim[indeks] = 42;    // cd'nin kutusunu deldik!
> ```

>
> Yukarıdada belirttim eğer sen kutuyu bilinçli olarak açıyorsan bu durumda cihazın garanti dışı kaldığınıda kabul etmiş olursun. Buna yapabilecek bir şey yok zaten, benim anlatmak istedigim kasıtlı olmayan durumlardı. Tıpkı hiç kimsenin bilinçli olarak hatalı kod yazmayacagı gibi ;)
>

Tabii ki. Dilim örneğine geri dönelim. Programcıyı kendisinden korumak için elemanlarına yazma erişimi sağlamadığımızı düşünelim. Yararlı mı olur?

Hmmm belki de sen elemanların veya topluluğun değişebilirliğinin zararlarını ortaya atıyorsun. Eğer eleman değiştirme veya popFront() olmasa hatalar da azalır. Fonksiyonel diller seninle aynı fikirdeler. :)

Ali

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

Alıntı (Kadir Can):

>

Eğer gerçekten ihtiyaç varsa aklıma şöyle bir çözüm geliyor;
Şimdi biz aralıkları, bazı işlevleri kullanabilmek için oluşturuyoruz.Eğer aralık işlevlerini uygun şekilde sarma uygularsak ve aralık işlevlerinden gerekenlerini kendi sınıfımız içinde gerçeklersek sorun kalmaz gibi geliyor.
Aşağıdaki gibi bir şey mi, Kadir? Bir nevi garanti belgesi ve/veya etiketiyle taşıdığımız bir CD-ROM driver oldu, değil mi? Belki Zafer'in ihtiyacına çözüm olur...

import std.stdio;

void main() {
   with(new Taşıyıcı (0, 10)) {
       foreach(i; Düzden) i.write("\t");
       writeln;
   }

   with(new Taşıyıcı (0, 10)) {
       foreach(i; Tersten) i.write("\t");
       writeln;
   }
}

class Taşıyıcı {
   private int[] veri;
   int başlangıç, bitiş;

   this (int baş, int bit) {
       başlangıç = baş;
       bitiş = bit;
   }
   ~this() {
       veri = veri[0..0]; // .init çalışmıyor ne hikmetse...
       // Error: null has no effect in expression (null)
   }
   private struct Aralık {
       int baş;
       int son;

       this(int baş, int son) {
           this.baş = baş;
           this.son = son;
       }
       bool empty() const {
           return baş == son;
       }
       void popFront() {
           ++baş;
       }
       void popBack() {
           --son;
       }
       int back() const {
           return son - 1;
       }
       int front() const {
           return baş;
       }
   }

   auto Düzden() {
       with(Aralık(başlangıç, bitiş)) {
           for ( ; !empty(); popFront()) {
               veri ~= front();
           }
       }
       return veri;
   }
   auto Tersten() {
       with(Aralık(başlangıç, bitiş)) {
           for ( ; !empty(); popBack()) {
               veri ~= back();
           }
       }
       return veri;
   }
}

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

July 10, 2012

Arkadaşlar iyi niyetiniz için çok teşekkürler ama sanırım benim kendimi ifade etme sorunum var.

Böyle bir çözümü zaten Ali ilk mesajında belirtmişti. Benim anlatmak istedigim bir fikir bir düşünceydi. Yani sınıfın doğası geregi metotoları erişim belirteci ile kısıtlamak varken neden kulağı tersten tutuyoruz sorusunun cevabını arıyordum.

Bu şartlar altında konuyu devam ettirmenin kendi adıma bir anlamı kalmadığını düşünüyor ve bu konuya katkı sağlayan tüm sevgili arkadaşlarıma çoook teşekkür ediyorum. :)

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