在Ruby中的块中更改上下文/绑定 [英] Change the context/binding inside a block in ruby

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

问题描述

我在Ruby中有一个DSL,其工作方式如下:

I have a DSL in Ruby that works like so:

desc 'list all todos'
command :list do |c|
  c.desc 'show todos in long form'
  c.switch :l
  c.action do |global,option,args|
    # some code that's not relevant to this question
  end
end

desc 'make a new todo'
command :new do |c|
  # etc.
end

一位开发人员建议我增强DSL,以免将c传递到command块,因此不需要所有c. 里面的方法;据推测,他暗示我可以使以下代码相同:

A fellow developer suggested I enhance my DSL to not require passing c to the command block, and thus not require the c. for all the methods inside; presumably, he implied I could make the following code work the same:

desc 'list all todos'
command :list do
  desc 'show todos in long form'
  switch :l
  action do |global,option,args|
    # some code that's not relevant to this question
  end
end

desc 'make a new todo'
command :new do
  # etc.
end

command的代码类似于

def command(*names)
  command = make_command_object(..)
  yield command                                                                                                                      
end

我尝试了几件事,但无法使其正常工作;我不知道如何更改command块中代码的上下文/绑定使其不同于默认值.

I tried several things and was unable to get it to work; I couldn't figure out how to change the context/binding of the code inside the command block to be different than the default.

关于这是否可行以及如何实现的任何想法?

Any ideas on if this is possible and how I might do it?

推荐答案

粘贴此代码:

  def evaluate(&block)
    @self_before_instance_eval = eval "self", block.binding
    instance_eval &block
  end

  def method_missing(method, *args, &block)
    @self_before_instance_eval.send method, *args, &block
  end

有关更多信息,请参见这篇非常好的文章此处

For more information, refer to this really good article here

这篇关于在Ruby中的块中更改上下文/绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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