4

In my program, I have a class that I want to be allocated before entering main(). I'd like to tuck these away in a separate module to keep the clutter out of my code; However, as soon as the module goes out of scope (before main() is entered), the objects are deallocated, leaving me trying to use a null reference in main. A short example:

// main.d

import SceneData;

int main(string[] argv)
{
    start.onSceneEnter();

    readln();
    return 0;
}

// SceneData.d

import Scene;

public
{
    Scene start;
}

static this()
{
    Scene start = new Scene("start", "test", "test";
}

// Scene.d

import std.stdio;

class Scene
{
    public
    {
        this(string name)
        {
            this.name = name;
        }

    this(string name, string descriptionOnEnter, string descriptionOnConnect)
    {
        this.name = name;
        this.descriptionOnEnter = descriptionOnEnter;
        this.descriptionOnConnect = descriptionOnConnect;
    }

        void onSceneEnter()
        {
            writeln(name);
            writeln(descriptionOnEnter);
        }
    }

    private
    {
        string name;
        string descriptionOnEnter;
        string descriptionOnConnect;
    }
}

I'm still getting used to the concept of modules being the basic unit of encapsulation, as opposed to the class in C++ and Java. Is this possible to do in D, or must I move my initializations to the main module?

Meta
  • 1,061
  • 5
  • 14

1 Answers1

4

Here:

static this()
{
    Scene start = new Scene("start", "test", "test");
}

"start" is a local scope variable that shadows global one. Global one is not initialized. After I have changed this to:

static this()
{
    start = new Scene("start", "test", "test");
}

Program crashed no more.

Mihails Strasuns
  • 3,677
  • 1
  • 16
  • 21
  • 1
    Ah, that's it. Funny how such an inconsequential lapse could cause such an annoying error. I guess this is why globals are a bad thing. – Meta Jan 25 '12 at 19:23
  • Probably it is worth filing an enhancement request to issue a warning in case of shadowing global variable with local one. Not sure about if this is a good idea at all, though. – Mihails Strasuns Jan 25 '12 at 19:39
  • 2
    Allowing the shadowing of global variables is on purpose. You wouldn't want to have your code break because a module that you're imported added a new global variable with the same name as one of your local variables. If you want to specifically access the shadowed variable, then prefix it with `.`. – Jonathan M Davis Jan 25 '12 at 23:31
  • Ye, that was exactly what made me doubt - too normal to be warning. I feel like usual scheme warning-error is not really enough as warning are most common treated as errors anyway. Something like "hint" in separate static analysis mode maybe? Problem is - it is a mistake easy to make and quite hard to spot for a newcomer. And I felt like D philosophy is exactly to prevent such scenarios as much as possible. – Mihails Strasuns Jan 26 '12 at 00:22
  • Shadowing a global in the same module,OTOH, might be an actionable case. – BCS Jan 26 '12 at 21:46