Thread overview
Mixin Templateler Çakışıyor Mu?
Jun 10, 2022
dunecourser
Jun 10, 2022
Ali Çehreli
Jun 11, 2022
dunecourser
Jun 10, 2022
Ali Çehreli
Jun 11, 2022
Salih Dincer
Jun 11, 2022
Ali Çehreli
June 10, 2022
Yorumları İngilizce yazdığıma bakmayın, Türkçeleştirmeye üşendim.

Diğer üşenenler için özet:

a. Bu basit bir kod. Yalnızca çok üyeli objelerin olabildiğince basit set ve get metotlarını tanımlama zahmetinden kurtulmak için yazıldı. (static foreach'in her döngüsünde typeid(typeof(member)) mevcut üyenin türünü de verebiliyor, yani metotlara typeof(%s) üzerinden member yollamak yerine direkt türü yollayabilirdim. Gelgelelim typeid() derleme zamanında çalışan bir olanak değilmiş, gerekçesini merak ettim.)

b. set ve get tek başlarına kullanıldıklarında, biri mixin edilip diğeri edilmediğinde çalışıyor. setget olarak yeni bir template'te birleştirildiğinde de çalışıyor.

c. set ve get yanyana mixin edildiğinde yerleştirilme sıralarına göre farklı hatalar veriyor.

--------------------------

mixin template set(S)
{
    import std.format : format;
    import std.string : capitalize;

    static foreach (member; __traits(allMembers, S))
        mixin(format!"public void set%s(typeof(%s) value) { %s = value; }"(
            capitalize(member), member, member));
}

mixin template get(S)
{
    import std.format : format;
    import std.string : capitalize;

    static foreach (member; __traits(allMembers, S))
        mixin(format!"public typeof(%s) get%s() const { return %s; }"(
            member, capitalize(member), member));
}

mixin template setget(S)
{
    import std.format : format;
    import std.string : capitalize;

    static foreach (member; __traits(allMembers, S))
    {
        // setter
        mixin(format!"public void set%s(typeof(%s) value) { %s = value; }"(
            capitalize(member), member, member));

        // getter
        mixin(format!"public typeof(%s) get%s() const { return %s; }"(
            member, capitalize(member), member));
    }
}

unittest // working nicely
{
    struct Man
    {
        private:
        bool married;
        bool childed;

        public:
        mixin setget!Man;
    }

    auto man = Man();

    assert(man.getMarried() == false);
    assert(man.getChilded() == false);

    man.setMarried(true);
    man.setChilded(true);

    assert(man.getMarried() == true);
    assert(man.getChilded() == true);
}

unittest // not working nicely
{
    struct Man
    {
        private:
        bool married;
        bool childed;

        public:
        // mixin get!Man;
        // mixin set!Man;
        // cannot have parameter of function type `const`
		
        // mixin set!Man;
        // mixin get!Man;
        // functions cannot return a function

        // NOTE: these template mixins are singly usable
    }

    // auto man = Man();

    // assert(man.getMarried() == false);
    // assert(man.getChilded() == false);

    // man.setMarried(true);
    // man.setChilded(true);

    // assert(man.getMarried() == true);
    // assert(man.getChilded() == true);
}
June 10, 2022
On 6/10/22 13:52, dunecourser wrote:

> typeid() derleme
> zamanında çalışan bir olanak değilmiş, gerekçesini merak ettim.

Çünkü typeid() nesnenin asıl türüyle ilgilidir ve asıl tür ancak çalışma zamanında bilinir. Örneğin, aşağıdaki kod derleme zamanında kullanılamaz çünkü Hayvan yerine Kedi, Köpek, vs. olabilir:

void foo(Hayvan hayvan) {
  typeid(hayvan);
}


>      static foreach (member; __traits(allMembers, S))
>          mixin(format!"public void set%s(typeof(%s) value) { %s = value;
> }"(
>              capitalize(member), member, member));
> }

Araya bir pragma(msg) yerleştirince durum anlaşıldı: :)

    static foreach (member; __traits(allMembers, S)) {
        pragma(msg, "mm ", member);
        mixin(format!"public void set%s(typeof(%s) value) { %s = value; }"(
            capitalize(member), member, member));
    }

mm married
mm childed
mm getMarried

Önceki mixin'in yerleştirdiği işlev bir sonrakinin allMembers'ı içinde beliriyor.

Acaba S.tupleof veya başka bir trait'ten yararlanılabilir mi?

Ali

June 10, 2022
On 6/10/22 13:52, dunecourser wrote:

> set ve get metotlarını tanımlama zahmetinden kurtulmak için yazıldı.

Ben de FieldNameTuple ve Fields ile biraz daha uğraştım ama garip hatalardan kurtulamadım. :/

Karşılaştırmış olmak için, Funkwerk'in koduna bakabiliriz[1]:

  https://code.dlang.org/packages/accessors

Ali

[1] Funkwerk, çok uzun zamandır D kullanan bir firmadır: https://funkwerk.com/en/

June 11, 2022
On Friday, 10 June 2022 at 22:06:17 UTC, Ali Çehreli wrote:
> Araya bir pragma(msg) yerleştirince durum anlaşıldı: :)
>
> mm married
> mm childed
> mm getMarried
>
> Önceki mixin'in yerleştirdiği işlev bir sonrakinin allMembers'ı içinde beliriyor.

Şöyle bir attım ama ne kadar doğrudur bilmiyorum: "O halde mixin template'lerimiz (mt) obje içinde bildirildiği anda kontrol ediliyor, elimizdeki mt validse hemen altında bildirilmiş diğer mt'e sıra gelmeden ifadeye dönüştürülüp, içinde olduğu objeyi kendi olmaksızın yeniden oluşturuyor"

Yukarda yazdığımdan ayrı olarak kodu azıcık okuyup düşündükten sonra problem ne kadar küçüldü ve basitleşti, pragma(msg) kullanmadan anlayamadığıma hayret ettim. :D

> Acaba S.tupleof veya başka bir trait'ten yararlanılabilir mi?

allMembers objede tanımlanan her şeyi kapsıyormuş meğer, çok tehlikeli. Şöyle hatalara da yol açıyor muhtemelen: setThis(), getThis(), set~this(), get~this(), setToString(), getToString(), setHerhangiBirFonksiyon, getHerhangiBirFonksiyon vb.
June 11, 2022

On Friday, 10 June 2022 at 20:52:15 UTC, dunecourser wrote:

>

a. Bu basit bir kod. Yalnızca çok üyeli objelerin olabildiğince basit set ve get metotlarını tanımlama zahmetinden kurtulmak için yazıldı. [...]

template'leri anlamak için güzel bir başlangıç uygulaması. Gel gelelim ben anlamıyor onları, var ben olmak. Ali topu at :)

Ama aklıma şu paket geldi:

https://code.dlang.org/packages/accessors

Özellikle read/write protect özniteliği ile çıtayı bir seviye üste çıkarmış. Sanırım D'de UDA diyorlar bunlara, var ben onları da anlamamak!

Başarılar...

June 11, 2022
On 6/10/22 22:53, Salih Dincer wrote:

> template'leri anlamak için güzel bir başlangıç uygulaması.

Şaka yapıyorsun. :) Hem çok ileri düzey olanaklar içeriyor hem de akıl almayan karmaşık durumlara düşürüyor.

Ali