为什么没有对象的`()`运算符?

Dar*_*yer 0 ruby lambda functional-programming

Ruby中的Lambdas(和procs)只是带有call方法的对象,就像任何OO语言一样,函数式编程作为事后的想法粘在上面.还有:

  • lambda.(<args>)
  • lambda[<args>]

作为语法糖lambda.call().

Lua允许一个__callmeta方法,它允许我调用一个对象,在后台,参数(和表)被传递给一个真正的函数来完成真正的魔术.

Lambdas不喜欢处理真正的函数,因为它们被调用[].()代替().为什么不添加()可以重载的运算符?然后object()将被转换为意味着object.(),同样的与+,||或任何其他操作.

拥有允许直接调用lambda的语法糖是不是有意义?这更像是设计哲学而非技术限制吗?

解决人们提出的一些"问题"(这不是真正的问题):

如果一个方法返回一个lambda,那个方法后跟()的意思是什么?它只调用方法,还是调用返回的lambda?

method()意味着呼叫method.如果该表达式返回一个lambda,method()()则会调用所述lambda.相反的情况根本就没有意义.

如果有一个名为foo的方法,以及一个名为foo的可调用对象,那么foo()是什么意思?

答:如果foo是一个方法和一个变量,你期望foo评估什么?变量.Ruby已经通过简单地选择更直观的两个选项来处理这种模糊性.因此,如果有方法foo,foo()应该调用该方法.如果foo在同一范围内存在可调用方法,则会被实际函数遮蔽.

Ste*_*fan 5

为什么不添加可以重载的()运算符?

这将是模棱两可的.如果object是方法和局部变量两者,则object引用局部变量,而object()调用方法:

def object
  123
end
object = :abc

object   #=> :abc
object() #=> 123
Run Code Online (Sandbox Code Playgroud)

更改此约定可能会破坏现有代码.

这(大概)是为什么Ruby有object.()- 它是语法糖object.call:

class MyClass
  def call
    123
  end
end

object = MyClass.new
object.call #=> 123
object.()   #=> 123
Run Code Online (Sandbox Code Playgroud)

使用单独的语法来调用lambdas可以区分方法调用和调用由该方法返回的lambda :(感谢Amadan指出这一点)

def object
  -> { 123 }
end

object    #=> #<Proc:0x007fe494110a78@(irb):2 (lambda)>
object()  #=> #<Proc:0x007fe494110a78@(irb):2 (lambda)>

object.()   #=> 123
object().() #=> 123
Run Code Online (Sandbox Code Playgroud)