2

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

このようなルビーのやり方を知りたいです。

4

3 に答える 3

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
于 2012-12-07T19:26:48.203 に答える
3

とを実装することで、独自のクラスをProcのように動作させることで、モンキーパッチを完全に回避できます(おそらくこの場合はそうすべきです)。たとえば、次のように開始できます。to_proccallOpenStruct

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]
于 2012-12-07T20:26:20.990 に答える
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について同じ考えを持っていました。彼の実装ははるかに優れています。

于 2012-12-07T19:35:08.377 に答える