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