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:
parent
34f4b91820
commit
5637037802
4 changed files with 47 additions and 24 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue