<div dir="ltr">On 13 April 2013 01:29, Vladimir Panteleev <span dir="ltr"><<a href="mailto:vladimir@thecybershadow.net" target="_blank">vladimir@thecybershadow.net</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="im">On Friday, 12 April 2013 at 14:58:10 UTC, Manu wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
I didn't see any attempt to index the array by key in this case. That's<br>
what an AA is for, and it's not being used here, so it's not a job for an<br>
AA.<br>
</blockquote>
<br></div>
Sorry, not following.<br>
<br>
Are you suggesting to use a dynamic array for creating processes, but an associative array for examining the current process's environment?</blockquote><div><br></div><div style>I didn't see anywhere where it was possible to example the current processed environment? I only saw the mechanism for feeding additional env vars to the system command.</div>
<div style>Linear array of key/value pair struct would be fine.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div class="im"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">I wouldn't use env ~= "FOO=BAR";<br>

I would use env ~= EnvVar("FOO", "BAR");<br>
Or whatever key/value pair structure you like.<br>
</blockquote>
<br></div>
OK, but I don't see how it changes your argument. Also, you mentioned string[] earlier.</blockquote><div><br></div><div style>Sorry. I didn't think it through at the time.</div><div style><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div class="im">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">It starts as soon as the majority agree it's important enough to enforce.<br>
</blockquote></div><div class="im"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Although I think a tool like: char[len] stackString; would be a<br>
super-useful tool to make this considerably more painless. Some C compilers<br>
support this.<br>
</blockquote>
<br></div>
I believe this is the feature:<br>
<br>
<a href="http://en.wikipedia.org/wiki/Variable-length_array" target="_blank">http://en.wikipedia.org/wiki/<u></u>Variable-length_array</a><br>
<br>
It is part of C99.<br>
<br>
------------------------------<u></u>------------------------------<u></u>-<br>
<br>
Earlier today, I wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Please rewrite some part of std.process with performance in mind, and post it here for review. This way, we can analyze the benefits and drawbacks based on a concrete example, instead of vapor and hot air.<br>
</blockquote>
<br>
I've tried doing this myself, for the bit of code you brought up (constructing environment variables). Here's what I ended up with:<br>
<br>
------------------------------<u></u>------------------------------<u></u>-<br>
<br>
import std.array;<br>
<br>
private struct StaticAppender(size_t SIZE, T)<br>
{<br>
    T[SIZE] buffer = void;<br>
    Appender!(T[]) appender;<br>
    alias appender this;<br>
}<br>
<br>
/// Returns a struct containing a fixed-size buffer and an<br>
/// appender. The appender will use the buffer (which has<br>
/// SIZE elements) until it runs out of space, at which<br>
/// point it will reallocate itself on the heap.<br>
auto staticAppender(size_t SIZE, T)()<br>
{<br>
    StaticAppender!(SIZE, T) result;<br>
    result.appender = appender(result.buffer[]);<br>
    return result;<br>
}<br>
<br>
/// Allows allocating a T[] given a size.<br>
/// Contains a fized-size buffer of T elements with SIZE<br>
/// length. When asked to allocate an array with<br>
/// length <= than SIZE, the buffer is used instead of<br>
/// the heap.<br>
struct StaticArray(size_t SIZE, T)<br>
{<br>
    T[SIZE] buffer = void;<br>
    T[] get(size_t size)<br>
    {<br>
        if (size <= SIZE)<br>
        {<br>
            buffer[0..size] = T.init;<br>
            return buffer[0..size];<br>
        }<br>
        else<br>
            return new T[size];<br>
    }<br>
}<br>
<br>
// ------------------------------<u></u>--------------------------<br>
<br>
void exec(const(char)*[] envz) { /+ ... +/ }<br>
<br>
void oldWay(string[string] environment)<br>
{<br>
    auto envz = new const(char)*[environment.<u></u>length + 1];<br>
    int pos = 0;<br>
    foreach (var, val; environment)<div class="im"><br>
        envz[pos++] = (var~'='~val~'\0').ptr;<br>
<br></div>
    exec(envz);<br>
}<br>
<br>
void newWay(string[string] environment)<br>
{<br>
    auto buf = staticAppender!(4096, char)();<br>
    StaticArray!(64, size_t) envpBuf;<br>
    size_t[] envp = envpBuf.get(environment.length + 1);<br>
<br>
    size_t pos;<br>
    foreach (var, val; environment)<br>
    {<br>
        envp[pos++] = buf.data.length;<br>
        buf.put(var);<br>
        buf.put('=');<br>
        buf.put(val);<br>
        buf.put('\0');<br>
    }<br>
<br>
    // Convert offsets to pointers in-place<br>
    auto envz = cast(const(char)*[])envp;<br>
    foreach (n; 0..pos)<br>
        envz[n] += cast(size_t)buf.data.ptr;<br>
<br>
    exec(envz);<br>
}<br>
<br>
------------------------------<u></u>------------------------------<u></u>-<br>
<br>
As you can see, the code is quite more verbose, even with the helper types. It's no longer obvious at a glance what the code is doing. Perhaps you can come up with better abstractions?<br>
</blockquote></div><br></div><div class="gmail_extra" style>Beautiful! Actually, I think if you look a couple of pages below, I think you'll see something rather like that already there in the windows code.</div><div class="gmail_extra" style>
<br></div><div class="gmail_extra" style>Thought not sure why you use a size_t array which you just cast to a char* array?</div><div class="gmail_extra" style>I think you could also fold that into one pass, rather than 2.</div>
<div class="gmail_extra" style>And I'm not sure about this line: envz[n] += cast(size_t)buf.data.ptr;</div><div class="gmail_extra" style><br></div><div class="gmail_extra" style>But those helpers make the problem rather painless.</div>
<div class="gmail_extra" style>I wonder if there's opportunity for improvement by having appender support the ~ operator? Might be able to jig it to use natural concat syntax rather than put()...</div></div>