1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-26 15:51:15 +02:00

* In the ‘?’ operator, allow attribute paths. For instance, you can

write ‘attrs ? a.b’ to test whether ‘attrs’ has an attribute ‘a’
  containing an attribute ‘b’.  This is more convenient than ‘attrs ?
  a && attrs.a ? b’.

  Slight change in the semantics: it's no longer an error if the
  left-hand side of ‘?’ is not an attribute set.  In that case it just
  returns false.  So, ‘null ? foo’ no longer throws an error.
This commit is contained in:
Eelco Dolstra 2011-07-06 10:58:17 +00:00
parent 34f4b91820
commit 5637037802
4 changed files with 47 additions and 24 deletions

View file

@ -656,9 +656,25 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v)
{
Value vAttrs;
state.evalAttrs(env, e, vAttrs);
mkBool(v, vAttrs.attrs->find(name) != vAttrs.attrs->end());
Value vTmp;
Value * vAttrs = &vTmp;
state.eval(env, e, vTmp);
foreach (AttrPath::const_iterator, i, attrPath) {
state.forceValue(*vAttrs);
Bindings::iterator j;
if (vAttrs->type != tAttrs ||
(j = vAttrs->attrs->find(*i)) == vAttrs->attrs->end())
{
mkBool(v, false);
return;
} else {
vAttrs = j->value;
}
}
mkBool(v, true);
}