如何更改lambda的上下文? [英] How do I change the context of lambda?

查看:72
本文介绍了如何更改lambda的上下文?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果运行下面的代码,则会出现错误.

If you run the code below you get an error.

class C
  def self.filter_clause param_1
    puts param_1
    yield # context of this param is class B
  end

  def hi
    "hello"
  end
end

class B
  def self.filter(value, lambda)
    code = lambda { filter_clause(value, &lambda) }
    C.instance_exec(&code)
  end

  filter(:name, ->{ hi })
end

错误是

NameError: undefined local variable or method `hi' for B:Class
from (pry):17:in `block in <class:B>'

据我了解,其原因是lambda在class B的上下文中运行.因此找不到方法def hi.我不知道如何使它在class C的上下文中运行.

From my understanding the reason for this is the lambda is running under the context of class B. So it can't find the method def hi. I can't figure out how to get it to run under the context of class C.

基本上,我希望能够注入在另一个接受参数和块的类中被调用的方法.

Essentially I want to be able to inject a method being called in another class that accepts an argument and a block.

例如:

filter_clause("value", ->{ hi })

这可能吗?

不确定我是否有道理.

推荐答案

您已经关闭.如果您希望lambda(/block,实际上)在C的实例的上下文中执行(因为hi是C上的实例方法),则需要实例化它,然后instance_exec将该块放在该新实例:

You're close. If you want the lambda(/block, really) to execute in the context of an instance of C (since hi is an instance method on C), then you'll need to instantiate it and then instance_exec the block on that new instance:

class C
  def self.filter_clause param_1, &block
    puts new.instance_exec &block
  end

  def hi
    "hello"
  end
end

class B
  def self.filter(value, lambda)
    code = lambda { filter_clause(value, &lambda) }
    C.instance_exec(&code)
  end

  filter(:name, ->{ hi })
end

# => hello

这篇关于如何更改lambda的上下文?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆