猴子修补和重载方法在Ruby中

时间:2012-12-07 19:19:01

标签: ruby metaprogramming overloading

我想扩展Proc类,以便它的构造函数也可以获取参数的哈希,并将其转换为带有一些元编程结构的方法。有什么影响:

p = Proc.new(this: 100, that: 200, yes: 1, no: 2) { |arg| arg.even? }
p.call(1) # => false
p.this # => 100
p.yes # => 1

我想知道做这样的事情的红宝石方式。

3 个答案:

答案 0 :(得分:3)

class Proc
  def initialize h; @h = h end
  def method_missing k; @h[k] end
  def respond_to_missing?; true end
end

p = Proc.new(this: 100, that: 200, yes: 1, no: 2) { |arg| arg.even? }
p.call(1) # => false
p.this # => 100
p.yes # => 1

答案 1 :(得分:3)

通过实现to_proccall,您可以(并且可能应该在这种情况下)通过让您自己的类行为像Proc一样完全避免猴子修补。例如,您可以从OpenStruct

开始
require 'ostruct'
class MyFunkyClass < OpenStruct
  def initialize(h, &block)
    @block = block
    super
  end

  def to_proc
    @block
  end

  def call(*args)
    @block.call(*args)
  end
end

f = MyFunkyClass.new(this: 100, that: 200, yes: 1, no: 2) { |arg| arg.even? }
f.that # => 200
f.call(42) # => true
[1,2,3,4].select(&f) # => [2, 4]

答案 2 :(得分:2)

没有元编程:

require 'ostruct'

r = OpenStruct.new(this: 100, that: 200, yes: 1, no: 2)
def r.call(n)
  n.even?
end

p r.this # 100
p r.call(1) # false

编辑:@ Marc-AndréLafortune对Openstruct有同样的想法;他的实施方式更好。