scala DSL 中的final == 和!=(等于和不等于)方法的解决方法

发布于 2024-10-03 02:37:25 字数 1260 浏览 6 评论 0原文

因此,我正在包装 Mechanical Turk API 的一些部分,并且您需要指定资格要求,例如:

Worker_Locale == "US"
Worker_PercentAssignmentsApproved > 95
...

在我的代码中,我希望允许使用上面的语法,并将这些内容翻译成类似这样的内容:

QualificationRequirement("00000000000000000071", "LocaleValue.Country", "EqualTo", "US")
QualificationRequirement("000000000000000000L0", "IntegerValue", "GreaterThan", 95)

我可以实现我的大部分目标 。

object Worker_PercentAssignmentsApproved {
  def >(x: Int) = {
    QualificationRequirement("000000000000000000L0", "IntegerValue", "GreaterThan", x)
  }
}

但我不能对“==”(等于)或“!=”(不等于)方法做同样的事情,因为它们在 AnyRef 中被声明为最终的 对此有标准的解决方法吗?也许我应该只使用“= =”和“!==”来代替?

(我想一个好的答案可能是总结一些不同的 scala DSL 如何选择解决这个问题,然后我就可以做大多数人所做的事情。)

编辑:请注意,我我并没有尝试实际执行相等比较。相反,我试图观察用户在 scala 代码中指示的比较运算符,保存该比较的基于对象的描述,并将该描述提供给服务器。具体来说,以下 scala 代码:

Worker_Locale == "US"

将导致以下参数被添加到我的请求中:

&QualificationRequirement.1.QualificationTypeId=000000000000000000L0
&QualificationRequirement.1.Comparator=EqualTo
&QualificationRequirement.1.LocaleValue.Country=US

因此我无法覆盖 equals 因为它返回一个 Boolean,并且我需要返回一个表示所有这些参数的结构。

So I'm wrapping bits of the Mechanical Turk API, and you need to specify qualification requirements such as:

Worker_Locale == "US"
Worker_PercentAssignmentsApproved > 95
...

In my code, I'd like to allow the syntax above and have these translated into something like:

QualificationRequirement("00000000000000000071", "LocaleValue.Country", "EqualTo", "US")
QualificationRequirement("000000000000000000L0", "IntegerValue", "GreaterThan", 95)

I can achieve most of what I want by declaring an object like:

object Worker_PercentAssignmentsApproved {
  def >(x: Int) = {
    QualificationRequirement("000000000000000000L0", "IntegerValue", "GreaterThan", x)
  }
}

But I can't do the same thing for the "==" (equals) or "!=" (not equals) methods since they're declared final in AnyRef. Is there a standard workaround for this? Perhaps I should just use "===" and "!==" instead?

(I guess one good answer might be a summary of how a few different scala DSLs have chosen to work around this issue and then I can just do whatever the majority of those do.)

Edit: Note that I'm not trying to actually perform an equality comparison. Instead, I'm trying to observe the comparison operator the user indicated in scala code, save an object based description of that comparison, and give that description to the server. Specifically, the following scala code:

Worker_Locale == "US"

will result in the following parameters being added to my request:

&QualificationRequirement.1.QualificationTypeId=000000000000000000L0
&QualificationRequirement.1.Comparator=EqualTo
&QualificationRequirement.1.LocaleValue.Country=US

So I can't override equals since it returns a Boolean, and I need to return a structure that represents all these parameters.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

相思碎 2024-10-10 02:37:25

如果您查看 scala 参考(第 12.1 节)中 ==!= 的定义,您会发现它们是根据 定义的eq等于

eq 是引用相等性,也是 final (在这种情况下它仅用于检查 null),但您应该能够覆盖等于

请注意,您可能还需要编写 hashCode 方法来确保
∀ o1, o2 与 o1.equals(o2)(o1.hashCode.equals(o2.hashCode))

但是,如果您的 DSL 需要除 Boolean 以外的其他返回类型或一般情况下需要更大的灵活性,则可能应该使用 ===,如 Squeryl

If you look at the definition of == and != in the scala reference, (§ 12.1), you’ll find that they are defined in terms of eq and equals.

eq is the reference equality and is also final (it is only used to check for null in that case) but you should be able to override equals.

Note that you’ll probably also need to write the hashCode method to ensure
∀ o1, o2 with o1.equals(o2)(o1.hashCode.equals(o2.hashCode)).

However, if you need some other return type for your DSL than Boolean or more flexibility in general, you should maybe use ===, as has been done in Squeryl for example.

幼儿园老大 2024-10-10 02:37:25

下面是对各种 DSL 在此类事情上的用途的一个小调查。

Liftweb 使用 ===< Javascript 表达式中的 /code>:

JsIf(ValById("username") === value.toLowerCase, ...)

Squeryl 使用 ===对于 SQL 表达式:

authors.where(a=> a.lastName === "Pouchkine")

querydsl 使用 $eq 对于 SQL 表达式:

person.firstName $eq "Ben"

Prolog-in-Scala使用 === 作为 Prolog 表达式:

'Z === 'A

Scalatest 使用 === 来获取 Option 而不是 Boolean

assert("hello" === "world")

所以我认为共识主要是使用<代码>===。

Here's a little survey of what various DSLs use for this kind of thing.

Liftweb uses === in Javascript expressions:

JsIf(ValById("username") === value.toLowerCase, ...)

Squeryl uses === for SQL expressions:

authors.where(a=> a.lastName === "Pouchkine")

querydsl uses $eq for SQL expressions:

person.firstName $eq "Ben"

Prolog-in-Scala uses === for Prolog expressions:

'Z === 'A

Scalatest uses === to get an Option instead of a Boolean:

assert("hello" === "world")

So I think the consensus is mostly to use ===.

你的他你的她 2024-10-10 02:37:25

我一直在考虑类似的问题。我正在考虑创建一个 DSL 来编写特定于领域的公式。问题是用户可能也想进行字符串操作,而你最终会得到这样的表达式:“

"some string" + <someDslConstruct>

无论你做什么,它都会将其词法为类似的东西”,

stringToLiteralString("some string" + <someDslConstruct>)

我认为摆脱这个坑的唯一潜在方法是尝试使用 。在您的示例中,也许您可​​以有一个宏来包装 scala 表达式并将原始 AST 转换为查询?对任意表达式执行此操作是不可行的,但如果您的域受到足够好的约束,那么它可能是一个可行的替代解决方案。

I've been considering a similar problem. I was thinking of creating a DSL for writing domain-specific formulas. The trouble is that users might want to do string manipulation too and you end up with expression like

"some string" + <someDslConstruct>

No matter what you do its going to lex this as a something like

stringToLiteralString("some string" + <someDslConstruct>)

I think the only potential way out of this pit would be to try using macros. In your example perhaps you could have a macro that wraps a scala expression and converts the raw AST into a query? Doing this for arbitrary expressions wouldn't be feasible but if your domain is sufficiently well constrained it might be a workable alternative solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文