Odersky认真对待“账单!*& ^%〜code!”?

时间:2010-04-27 21:54:24

标签: syntax scala obfuscation puzzle

他在scala编程中的书(第5章第5.9节第93页) 奥德斯基提到了这个表达“bills !*&^%~ code!

在同一页的脚注中:

“到现在为止,你应该能够弄清楚,鉴于此代码,Scala编译器将

调用(bills.!*&^%~(code)).!()."

这对我来说有点神秘,有人可以解释这里发生了什么吗?

4 个答案:

答案 0 :(得分:9)

奥德斯基的意思是说有可能拥有这样的有效代码。例如,下面的代码:

class BadCode(whose: String, source: String) {
  def ! = println(whose+", what the hell do you mean by '"+source+"'???")
}

class Programmer(who: String) {
  def !*&^%~(source: String) = new BadCode(who, source)
}

val bills = new Programmer("Bill")
val code = "def !*&^%~(source: String) = new BadCode(who, source)"
bills !*&^%~ code!

只需将其复制并粘贴到REPL上即可。

答案 1 :(得分:3)

对于调用采用单个参数的方法或具有空参数列表的方法,句点是可选的。

使用此功能时,假定方法名称后面的空格后面的下一个块是单个参数。

因此,

(!票据*安培; ^%〜(代码))。!()

相同

账单!*& ^%〜代码!

第二个感叹号调用第一个方法调用返回值的方法。

答案 2 :(得分:2)

我不确定这本书是否提供了方法签名,但我认为它只是对Scala的语法糖的评论,所以它假定你键入:

bill add monkey

其中有一个对象bill,它有一个带有参数的方法add,然后它自动将其解释为:

bill.add(monkey)

作为一个小Scala生锈,我不完全确定它如何拆分代码!进入(代码)。!()除了模糊的灰色细胞痒!运算符用于触发一个actor,它在编译器术语中可能被解释为对象的隐式。!()方法。

答案 3 :(得分:2)

'。()'与方法调用是可选的组合(如上所述Wysawyg)和使用(几乎)任何你喜欢的字符命名方法的能力,使得在Scala中编写看起来像的方法成为可能运算符重载。你甚至可以创建自己的运营商。

例如,我有一个处理3D计算机图形的程序。我有自己的班级Vector来表示3D矢量:

class Vector(val x: Double, val y: Double, val z: Double) {
    def +(v: Vector) = new Vector(x + v.x, y + v.y, z + v.z)

    // ...etc.
}

我还定义了一个方法**(上面未显示)来计算两个向量的cross product。在Scala中创建自己的运算符非常方便,没有多少其他编程语言具有这种灵活性。