在Rego中,“every”为什么从不为false?

huangapple go评论49阅读模式
英文:

In Rego, why is "every" never false?

问题

根据Open Policy Agent文档,在Rego中,every评估为trueundefined。为什么不是truefalse?在Rego中有什么暗示false是错误的值?与此相比,成员运算符in总是评估为truefalse,这更符合我对every的期望。

我找到了关于falseundefined之间区别的解释,但我并没有找到它很有启发性。

undefinedfalse之间的区别在于,Rego中的undefined不是您可以在Rego中引用的值(而false只是另一个JSON值而已)。在查询和规则评估方面,undefinedfalse的行为相同。为了使查询成功(或者使规则生成一个值),查询中的所有语句(或规则的主体)都必须为真。在Rego中,除了undefinedfalse之外的所有值都被视为真。

显然,Rego在使用undefined方面与其他语言不同,其他语言中通常表示某种信息缺失。例如,在JavaScript中,如果引用已声明但尚未初始化的变量,其值为undefined。然而,在这个Rego示例中,every完全定义,但无论如何都评估为undefined,而不是false

因此,在Rego中,使用undefined背后的哲学是什么,为什么every评估为undefined而不是false

英文:

According to the Open Policy Agent documentation, in Rego, every evaluates either to true or undefined. Why not true or false? What is it about Rego that suggests false is the wrong value? By comparison, the membership operator in always evaluates to true or false, which is more in line with my expectations for every.

I found this explanation of the difference between false and undefined but I did not find it enlightening.

> The difference between undefined and false is that undefined in Rego is not a value you can refer to in Rego (whereas false is just another JSON value.) With respect to how queries and rules evaluated, undefined and false behave the same. In order for a query to succeed (or for a rule to produce a value) ALL of the statements in the query (or body of the rule) must be true. In Rego, all values except undefined and false are considered true.

Clearly Rego is using undefined in a way that is different than other languages, where it usually indicates some kind of information is missing. For example, in JavaScript, if you refer to a variable that has been declared but has not been initialized, its value is undefined. In this Rego example, though, every is completely defined, but evaluates to undefined instead of false anyway.

So, in Rego, what is the philosophy behind the use of undefined and why does every evaluate to undefined instead of false?

答案1

得分: 1

这是我第一次听说Rego,所以我去看了他们的文档来尝试帮助,我会分享我理解的内容。

基础部分的这个例子中:

你可以使用规则定义一个新概念。例如,下面的v在等式表达式为true时为true

v if "hello" == "world"

如果我们评估v,结果将是undefined,因为规则的主体从不评估为true。因此,由规则生成的文档未定义。

你可以看到在Rego中应该如何思考,就像你把v放在那里然后执行表达式,如果它是“truthy”,那么v将接收到true,否则v不会受影响,它是undefined

引用undefined值的表达式也是undefined。这包括!=等比较。

v == true // 未定义决策
v != true // 未定义决策

除了undefinedfalse以外,所有值都被视为true

所以falseundefined一样独特,但真正的区别在于:

false只是另一个JSON值

而Rego使用JSON比较,所以它将被检测为JSON,然后被识别为false,这就是为什么我们希望给出undefined而不是false的原因。

我对false及其用例感到好奇,我在这里找到了这个例子:

default allow := false

allow if {
    input.user == "bob"
    input.method == "GET"
}

allow if input.user == "alice"

在这里,我们使用default关键字将allow初始化为false,所以即使它不受条件影响,它也是false

没有default定义,相同输入的allow文档将简单地是undefined

我仍然看不出这是否有用,因为:

undefinedfalse的行为相同。为了使查询成功(或使规则产生一个值),查询中的所有语句(或规则的主体)都必须为true

所以我仍然可以将allow视为undefined

**注意:**上面的例子来自default关键字部分。

另一个例子是在问题中提到的,成员运算符inevery关键字

我发现它与这个类似:

v if "hello" == "world"

我们只是用“成员运算符in”代替了if "hello" == "world",用every代替了v

every server in site.servers {
  endswith(server.name, "-dev")
}

用相同的逻辑,规则的结果将是truefalse,然后every将是trueundefined

成员运算符in 是一个函数,不是像vevery那样定义的概念,它被设计成返回truefalse,所以我们用它来定义every,对我来说很有意义。

英文:

It is the first time I heard about Rego so I went to their docs trying to help and I'll share what I understood.<br>

from this example here in the basics section:

>You can define a new concept using a rule. For example, v below is true if the equality expression is true.

v if &quot;hello&quot; == &quot;world&quot;

>If we evaluate v, the result is undefined because the body of the rule never evaluates to true. As a result, the document generated by the rule is not defined.

you can see how you should think in Rego, it is like you put v there and then execute the expression if it is "truthy" then v will receive true otherwise v won't be affected and it is undefined.

>Expressions that refer to undefined values are also undefined. This includes comparisons such as !=

v == true // undefined decision
v != true // undefined decision

>all values except undefined and false are considered true

so false is unique as undefined but the real difference is that

>false is just another JSON value

and Rego uses JSON comparison so it will be detected as JSON and then recognized as false that's why we want to give undefined instead so we avoid that.

I wondered about false and its use cases, I found this example here:

default allow := false

allow if {
    input.user == &quot;bob&quot;
    input.method == &quot;GET&quot;
}

allow if input.user == &quot;alice&quot;

here we initialize allow with the default keyword to false so even if it won't be affected by the condition it is false.<br>

>Without the default definition, the allow document would simply be undefined for the same input.

still cannot see if this is useful since:

>undefined and false behave the same. In order for a query to succeed (or for a rule to produce a value) ALL of the statements in the query (or body of the rule) must be true.

so I still can deal with allow as undefined
note: the above example is from the default keyword section.

another example is the one mentioned in the question, the membership operator in with the every keyword

I found it similar to this one:

v if &quot;hello&quot; == &quot;world&quot;

we just replaced if &quot;hello&quot; == &quot;world&quot; with the "the membership operator in" and v with every:

every server in site.servers {
  endswith(server.name, &quot;-dev&quot;)
}

with the same logic, the result of the rule will be either true or false then every is either true or undefined.

the the membership operator in is a function it is not a concept to define like v and every, and it is designed to return true or false so we use it to define every, makes sense to me.

huangapple
  • 本文由 发表于 2023年6月19日 14:44:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76504211.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定