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

时间:2017-11-21 07:21:49

标签: ruby lambda functional-programming

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

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

作为lambda.call()的语法糖。

Lua允许使用__call元方法,它允许我调用一个对象,并且在后台,参数(和表)被传递给一个真正的函数来实现真正的魔法。

Lambdas不想处理实际函数,因为它们是使用[].()而不是()调用的。为什么不添加可以重载的()运算符?然后,object()将被翻译为object.(),与+||或任何其他运营商相同。

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

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

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

method()表示致电method。如果该表达式返回lambda,则method()()将调用所述lambda。反之亦然。

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

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

1 个答案:

答案 0 :(得分:5)

  

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

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

def object
  123
end
object = :abc

object   #=> :abc
object() #=> 123

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

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

class MyClass
  def call
    123
  end
end

object = MyClass.new
object.call #=> 123
object.()   #=> 123

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

def object
  -> { 123 }
end

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

object.()   #=> 123
object().() #=> 123