On Wed, 13 Mar 2013 02:45:57 -0400, dennis luehring <[email protected]>
wrote:

Am 13.03.2013 07:31, schrieb Lars T. Kyllingstad:
On Wednesday, 13 March 2013 at 03:27:25 UTC, Vladimir Panteleev
wrote:
On Tuesday, 12 March 2013 at 21:39:47 UTC, Steven Schveighoffer
wrote:
I'd be very interested to hear if you have a suggestion for a
better way to do it, keeping in mind that there needs to be
*some* way to clear the environment too.

Sadly, no I don't.  I had hoped [] would allocate an empty AA,
but it fails to compile.

Note that you can "hack" it by setting a single environment
variable which nobody will ever use.

i.e. spawnProcess("blah.exe", ["_____":"_____"]);

But that is really, really ugly.

How about this:

@property string[string] emptyEnvironment()
{
    string[string] result;
    result["a"] = "a";
    result.remove("a");
    assert(result && result.length == 0);
    return result;
}

(can be cached to avoid allocating each time)

That's a lot better than ["____":"_____"], at least. :)

But still, the difference between a null AA and an empty AA is
still very subtle, and I am hesitant to design an API that
depends on it.  We'd have to explain to the users that "ok, so
there are two kinds of empty AAs: the ones you've done nothing
with, and the ones you've added and removed a value from..."

Furthermore, the language spec doesn't seem to mention "null" in
relation to AAs.  Shouldn't the difference between null and empty
then be treated as an implementation detail?  Can we even be sure
that "aa is null" will work in two years?

Lars


why not differentiate on callsite?

like

environment_usage =
{
   PARENT_ENVIRONMENT,
   NONE_ENVIRONMENT, // which differs from empty given environment
   GIVEN_ENVIRONMENT
}

spawnProcess(process,parameter,environment_usage = PARENT_ENVIRONMENT, environemnt = null)

it feels very wrong to put the environment "usage" type in any way into the environment-abstraction itself (by occupying null or empty...)

+some nice helpers

spawnProcessWithParentEnvironment((process,parameter)
spawnProcessWithoutEnvironment((process,parameter)
spawnProcessWithEnvironment((process,parameter,environment=...)

woulnd't that be much clearer?

the other way could be an

spawnProcess(process,parameter,environment=use_parent_environment());
with parent-environment selector

spawnProcess(process,parameter,environment=given_environment(environment));

Hm.. I think I actually like this.

I hate to have feature creep at this point, but one kind of annoying thing
is, if you want to *add* to the current environment, it is a multi-step
process:

auto curenv = environment.toAA;
curenv["x"] = "y";
spawnProcess("helloworld", curenv);

But with something similar to Dennis' idea, we have a possible way to do
that without making a copy of the current environment into an AA and
adding:

struct EnvironmentArg
{
     this(string[string] env, bool useParent=false) { this.env = env;
this.useParent = useParent;}
     this(bool useParent) {this.useParent = useParent;}
     string[string] env;
     bool useParent;
}

spawnProcess("helloworld", EnvironmentArg(["x":"y"], true)); // use parent
environment, add x=y
spawnProcess("helloworld", EnvironmentArg(["x":"y"])); // replace
environment with x=y
spawnProcess("helloworld", EnvironmentArg(false)); // use empty environment
spawnProcess("helloworld", EnvironmentArg(true)); // use parent
environment exactly

EnvironmentArg should probably have better name, and I would recommend
some global functions that make common things, like:

EnvironmentArg emptyEnvironment() { return EnvironmentArg(null, false);}
EnvironmentArg parentEnvironment() { return EnvironmentArg(null, true);}

Like? Hate?

-Steve

Reply via email to