Thread overview
auto scope question?
Oct 25, 2022
WhatMeWorry
Oct 25, 2022
Ali Çehreli
Oct 26, 2022
WhatMeWorry
October 25, 2022

I'm naturally getting a undefined identifier s error in the return. Is there some way to refactor my code? I tried to declare s outside of the else brackets like:

auto screen = executeShell(cmdLine);
auto s;
...
{
s = screen.output.findSplit("REG_SZ");
}

but that doesn't compile either.

string[] getPath(string cmdLine)
{
auto screen = executeShell(cmdLine);

if (screen.status != 0)
{
    writeln(cmdLine, " failed");
}
else
{
    writeln("screen.output = ", screen.output);	
auto s = screen.output.findSplit("REG_SZ");
    writeln("s[0] = ", s[0]);
    writeln("s[1] = ", s[1]);
    writeln("s[2] = ", s[2]);		
}
return (s.split(';'));  // Error: undefined identifier `s`

}

October 25, 2022
On 10/25/22 15:07, WhatMeWorry wrote:

> auto screen = executeShell(cmdLine);
> auto s;

That can't work because there is no information to infer the type of 's'. Judging from the return type of getPath, perhaps it's string[]:

string[] s;

This is the question we should answer first: What should happen when executeShell fails?

a) It is an error; the program should not continue. Then we can use 'enforce' (this is my way of coding):

string[] getPath(string cmdLine)
{
    import std.exception : enforce;

    auto screen = executeShell(cmdLine);
    enforce(screen.status == 0, format!"%s failed:\n%s"(cmdLine, screen.output));

    writeln("screen.output = ", screen.output);
    auto s = screen.output.findSplit("REG_SZ");
    writeln("s[0] = ", s[0]);
    writeln("s[1] = ", s[1]);
    writeln("s[2] = ", s[2]);

    return (s.split(';'));
}

b) It is not an error; getPath() should return empty array:

string[] getPath(string cmdLine)
{
    string[] result;
    auto screen = executeShell(cmdLine);

    if (screen.status != 0)
    {
        writeln(cmdLine, " failed");
        return null;  // <-- HERE (null converts to any array type)
    }
    else
    {
        // ...
        // Now, 'return' is where 's' is defined:
        return (s.split(';'));
    }
}

Ali

October 25, 2022
On 10/25/22 6:07 PM, WhatMeWorry wrote:
> I'm naturally getting a undefined identifier `s` error in the return.  Is there some way to refactor my code?  I tried to declare s outside of the else brackets like:
> 
> auto screen = executeShell(cmdLine);
> auto s;
> ...
> {
>      s = screen.output.findSplit("REG_SZ");
> }
> 
> but that doesn't compile either.
> 
> 
> 
> string[] getPath(string cmdLine)
> {
>      auto screen = executeShell(cmdLine);
> 
>      if (screen.status != 0)
>      {
>          writeln(cmdLine, " failed");
>      }
>      else
>      {
>          writeln("screen.output = ", screen.output);
>      auto s = screen.output.findSplit("REG_SZ");
>          writeln("s[0] = ", s[0]);
>          writeln("s[1] = ", s[1]);
>          writeln("s[2] = ", s[2]);
>      }
>      return (s.split(';'));  // Error: undefined identifier `s`
> }

As Ali mentioned, your logic is faulty -- you seem to write that the command failed, but then return something anyway.

Also, you are returning `string[]`, so just declaring `string[] s;` should be enough.

However, I did want to mention that if you do want to hoist a difficult to name type outside where it is declared with an auto, you can use `typeof`:

```d
typeof(screen.output.findSplit("")) s;
```

In this case, it's just `string[]`, but the idea here is you can name a type without naming it, by using `typeof` on the expression you would have called.

Hope this helps further your D knowledge ;)

-Steve
October 26, 2022
typeof(screen.output.findSplit("")) s;


Perfect. That was the "essence" of my question. But thanks to Ali, I don't have to use such esoteric syntax.  D is a wonderful language, but I seem to shoot myself in the foot :)