有没有办法避免在lambdas和procs上写“.call”?

时间:2013-10-16 10:03:51

标签: ruby

我经常在我的函数中创建小lambda来处理重复的任务,例如(人为的例子):

def some_method(foo)
  match = SOME_REGEX.match foo

  has_component = lambda { |name|
    match.names.include? name and not match[name].nil?
  }

  if has_component.call("street_name")
    # ...
  end

  if has_component.call("house_number")
    # ...
  end

  if has_component.call("entrance")
    # ...
  end

  # ...
end

现在我不了解你,但我更愿意写:

  if has_component "street_name"
    # ...
  end

  if has_component "house_number"
    # ...
  end

  if has_component "entrance"
    # ...
  end

我不熟悉Ruby的内部工作原理,但是我能用lambda / proc做些什么来使它可以调用,好像它是一个def函数一样?

我不希望在类级别将lambda / proc定义为方法,这有很多原因。除此之外,它无法访问调用者的范围。

3 个答案:

答案 0 :(得分:2)

您可以使用下标运算符

if has_component['entrance']

答案 1 :(得分:2)

你也可以这样做:

has_component.('entrance')

答案 2 :(得分:1)

从Ruby 1.9.0开始,call有语法糖:

b.call(1, 2, 3)
b.(1, 2, 3)

这是首选方式,因为它适用于响应call所有,而不仅仅是Proc

或者,您可以定义一个较短的方法名称:

class Proc
  alias_method :c, :call
end

b.c(1, 2, 3)

或更短的方法名称:

class Proc
  alias_method :[], :call
end

c[1, 2, 3]

事实上,后者已经在Ruby核心库中定义了。

无法使调用Proc看起来像调用方法,因为存在歧义:b(1, 2, 3)是否意味着"调用方法b带有参数{{1 }}"或者它是否意味着没有参数调用方法1, 2, 3(或取消引用局部变量b)并使用参数b调用Proc返回的b &#34 ;?在ECMAScript和Python中,这是有效的,因为它们不允许在没有括号的情况下调用方法,因此这种模糊性从未出现过。