www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - Is a template like copy-paste?

reply Ary Manzana <asterite gmail.com> writes:
I have a template for singleton:

---
template Singleton() {

    private static typeof(this) _instance;
    private this() { }

    public static typeof(this) instance() {
        if (!_instance) {
            _instance = new typeof(this)();
        }
        return _instance;
    }

}
---

I use it like this:

---
class Bla { // Line 15

    mixin Singleton!();

}

void main() {
     Bla bla = Bla.instance;
}
---

The compiler says:
main.d(15): class main.Bla main.Bla.Singleton!().this is private

Then I copy-paste the template into the class definition, to see what 
happens:

---
class Bla {

    private static typeof(this) _instance;
    private this() { }

    public static typeof(this) instance() {
        if (!_instance) {
            _instance = new typeof(this)();
        }
        return _instance;
    }

}

void main() {
     Bla bla = Bla.instance;
}
---

Compiles fine.

If I change "private this() { }" to "protected this() { }" in the 
singleton template, both compile fine. However, this is just a 
workaround, the first should also work.
Oct 27 2006
next sibling parent Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
Ary Manzana wrote:
 I have a template for singleton:
 
 ---
 template Singleton() {
 
    private static typeof(this) _instance;
    private this() { }
 
    public static typeof(this) instance() {
        if (!_instance) {
            _instance = new typeof(this)();
        }
        return _instance;
    }
 
 }
 ---
 
 I use it like this:
 
 ---
 class Bla { // Line 15
 
    mixin Singleton!();
 
 }
 
 void main() {
     Bla bla = Bla.instance;
 }
 ---
 
 The compiler says:
 main.d(15): class main.Bla main.Bla.Singleton!().this is private
 
 Then I copy-paste the template into the class definition, to see what 
 happens:
 
 ---
 class Bla {
 
    private static typeof(this) _instance;
    private this() { }
 
    public static typeof(this) instance() {
        if (!_instance) {
            _instance = new typeof(this)();
        }
        return _instance;
    }
 
 }
 
 void main() {
     Bla bla = Bla.instance;
 }
 ---
 
 Compiles fine.
 
 If I change "private this() { }" to "protected this() { }" in the 
 singleton template, both compile fine. However, this is just a 
 workaround, the first should also work.

First off, very nifty to use typeof() in a Singleton template! I never even tried that. Secondly, consider moving the _instance static variable into the instance() function... maybe its just me, but I tend to find that cleaner. :) Different strokes, maybe. Third, technically no templates aren't quite like copy-paste. The issue is, mixins have their own scope. Protected is the way to go; besides, it makes your Singleton class derivable. Consider it a bonus feature. Personally, I'd always just put the instance() function into the template, and expected the class designer to be intelligent enough to make the constructor protected/private, otherwise you're screwed if your Singleton needs to do any startup work. -- Chris Nicholson-Sauls
Oct 27 2006
prev sibling next sibling parent Sean Kelly <sean f4.ca> writes:
Ary Manzana wrote:
 I have a template for singleton:
 
 ---
 template Singleton() {
 
    private static typeof(this) _instance;
    private this() { }
 
    public static typeof(this) instance() {
        if (!_instance) {
            _instance = new typeof(this)();
        }
        return _instance;
    }
 
 }
 ---
 
 I use it like this:
 
 ---
 class Bla { // Line 15
 
    mixin Singleton!();
 
 }
 
 void main() {
     Bla bla = Bla.instance;
 }
 ---
 
 The compiler says:
 main.d(15): class main.Bla main.Bla.Singleton!().this is private
 
 Then I copy-paste the template into the class definition, to see what 
 happens:
 
 ---
 class Bla {
 
    private static typeof(this) _instance;
    private this() { }
 
    public static typeof(this) instance() {
        if (!_instance) {
            _instance = new typeof(this)();
        }
        return _instance;
    }
 
 }
 
 void main() {
     Bla bla = Bla.instance;
 }
 ---
 
 Compiles fine.
 
 If I change "private this() { }" to "protected this() { }" in the 
 singleton template, both compile fine. However, this is just a 
 workaround, the first should also work.

Templates are like a form of structured macro expansion, but you're dealing with mixins, not templates per se. mixins work just like import, so you can consider Singleton to be like its own little module being imported into the scope of Bla. privates in Singleton, then, are not visible to Bla. Sean
Oct 27 2006
prev sibling parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Ary Manzana wrote:
 I have a template for singleton:
 
 ---
 template Singleton() {
 
    private static typeof(this) _instance;
    private this() { }
 
    public static typeof(this) instance() {
        if (!_instance) {
            _instance = new typeof(this)();
        }
        return _instance;
    }
 
 }
 ---
 
 I use it like this:
 
 ---
 class Bla { // Line 15
 
    mixin Singleton!();
 
 }
 
 void main() {
     Bla bla = Bla.instance;
 }
 ---
 
 The compiler says:
 main.d(15): class main.Bla main.Bla.Singleton!().this is private
 
 Then I copy-paste the template into the class definition, to see what 
 happens:
 
 ---
 class Bla {
 
    private static typeof(this) _instance;
    private this() { }
 
    public static typeof(this) instance() {
        if (!_instance) {
            _instance = new typeof(this)();
        }
        return _instance;
    }
 
 }
 
 void main() {
     Bla bla = Bla.instance;
 }
 ---
 
 Compiles fine.
 
 If I change "private this() { }" to "protected this() { }" in the 
 singleton template, both compile fine. However, this is just a 
 workaround, the first should also work.

Consider: http://d.puremagic.com/bugzilla/show_bug.cgi?id=49 (that bug reported is outdated though, it needs to be updated) -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Oct 31 2006