How to simplify nested ifs

bauss jj_1337 at live.dk
Fri Mar 16 10:44:52 UTC 2018


On Tuesday, 13 March 2018 at 12:23:06 UTC, Ozan Süel wrote:
> Hi
>
> I have a construction like the following
>
> if (source) {
>   if (source.pool) {
>     if (source.pool.repository) {
>       if (source.pool.repository.directory) {
> 	if (source.pool.repository.directory.users) {
> 	  // do something
>
> Any chance to simplify this nested ifs?
> I know some languages has a way like.
>
> if (source?pool?repository?directory?users) // do something
>
>
> Similar ways in D?
>
> Thanks and Regards, Ozan

Kind of an ugly hack, but:

string createCondition(string[] entries)
{
     string result = "";
     string lastEntry = "";

     foreach (entry; entries)
     {
         if (lastEntry && lastEntry.length) lastEntry ~= "." ~ 
entry;
         else lastEntry = entry;

         result ~= lastEntry ~ " !is null &&";
     }

     result.length -= 2;

     return result;
}

bool isDefined(alias symbol,T)(T arg)
{
     import std.array : split;

     enum symbolEntries = symbol.split(".");

     enum entriesCondition = createCondition(["arg"] ~ 
symbolEntries[1..$]);

     mixin("return " ~ entriesCondition ~ ";");
}

...

Usage:

Let's say we have these:

class A {}

class B { A a; }

class C { B b; }

class D { C c; }

class E { D d; }

Then instead of:

auto e = new E;

if (e !is null && e.d !is null && e.d.c !is null && e.d.c.b !is 
null && e.d.c.b.a !is null)
{
     // ...
}

Then we can just do:

if (isDefined!((e.d.c.b.a).stringof)(e))
{
    // ...
}

...

The ugly part tbh.

is that we need to stringof when passing the symbol and we also 
have to pass the object itself to the function.

A preferred version would have been:

if (isDefined!(e.d.c.b.a))
{
    // ...
}

Unfortunately that's not possible.

You can see it live here: https://run.dlang.io/is/e2ACNc


More information about the Digitalmars-d-learn mailing list