简体   繁体   English

如何编写ruby方法来接受并保存lambda,block或Proc?

[英]How can I write a ruby method to accept and save a lambda, block, or Proc?

In ruby, I want to create a method on a class which will save a callable object of any sort into an instance variable. 在ruby中,我想在类上创建一个方法,它将任何类型的可调用对象保存到实例变量中。 This includes lambdas, blocks, and Procs. 这包括lambdas,blocks和Procs。 For example: 例如:

obj.save_callable(lambda { |x| x * 2 })
assert_equal(10, obj.invoke_callable(5))

obj.save_callable { |x| x * 3 }
assert_equal(15, obj.invoke_callable(5)) 

obj.save_callable(Proc.new { |x| x * 4 })
assert_equal(20, obj.invoke_callable(5)) 

I know this can be a hairy area. 我知道这可能是一个毛茸茸的地方。 One approach that I've already seen is to create different methods, one for each type: 我已经看到的一种方法是创建不同的方法,每种方法一种:

class MyClass
  # pass proc or lambda
  def save_callable(p)
    @callable = p
  end

  # pass a block
  def save_callable_block(&b)
    @callable = b
  end

  def invoke_callable(*args)
    @callable && @callable.call(*args)
  end
end

Question: Is there some way to boil this down further to just a single save_callable method? 问题:有没有办法将其进一步save_callable一个 save_callable方法?

Alright... after writing this question, on a lark, I tried the following. 好吧......在写完这个问题之后,我尝试了以下内容。 This actually appears to work in both ruby 1.8.7 and 1.9.2: 这实际上似乎适用于ruby 1.8.7和1.9.2:

class UnifiedSaveCallable
  def save_callable(p=nil, &b)
    @callable = p || b
  end
  def invoke_callable(*args)
    @callable && @callable.call(*args)
  end
end

obj = UnifiedSaveCallable.new

obj.save_callable(lambda { |x| x * 2 })
assert_equal(10, obj.invoke_callable(5))

obj.save_callable { |x| x * 3 }
assert_equal(15, obj.invoke_callable(5)) 

obj.save_callable(Proc.new { |x| x * 4 })
assert_equal(20, obj.invoke_callable(5)) 

This idiom seems to work for me. 这个成语似乎对我有用。 Still interested in hearing if there's a better or more idiomatic way to do this in ruby. 仍然有兴趣听听是否有更好或更惯用的方式在红宝石中这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM