I got the compilation error in the subject line when trying to create a range via std.range.generate. Turns out this was caused by trying to create a closure for 'generate' where the closure was accessing a struct containing a destructor.

The fix was easy enough: write out the loop by hand rather than using 'generate' with a closure. What I'm wondering/asking is if there alternate way to do this that would enable the 'generate' approach. This is more curiosity/learning at this point.

Below is a stripped down version of what I was doing. I have a struct for output buffering. The destructor writes any data left in the buffer to the output stream. This gets passed to routines performing output. It was this context that I created a generator that wrote to it.

----example.d-----
struct BufferedStdout
{
    import std.array : appender;

    private auto _outputBuffer = appender!(char[]);

    ~this()
    {
        import std.stdio : write;
        write(_outputBuffer.data);
        _outputBuffer.clear;
    }

    void appendln(T)(T stuff)
    {
        import std.range : put;
        put(_outputBuffer, stuff);
        put(_outputBuffer, "\n");
    }
}

void foo(BufferedStdout output)
{
    import std.algorithm : each;
    import std.conv : to;
    import std.range: generate, takeExactly;
    import std.random: Random, uniform, unpredictableSeed;

    auto randomGenerator = Random(unpredictableSeed);
auto randomNumbers = generate!(() => uniform(0, 1000, randomGenerator));
    auto tenRandomNumbers = randomNumbers.takeExactly(10);
    tenRandomNumbers.each!(n => output.appendln(n.to!string));
}

void main(string[] args)
{
    foo(BufferedStdout());
}
----End of  example.d-----

Compiling the above results in:

   $ dmd example.d
example.d(22): Error: variable `example.foo.output` has scoped destruction, cannot build closure

As mentioned, using a loop rather than 'generate' works fine, but help with alternatives that would use generate would be appreciated.

The actual buffered output struct has more behind it than shown above, but not too much. For anyone interested it's here: https://github.com/eBay/tsv-utils/blob/master/common/src/tsvutil.d#L358

Reply via email to