'eval'是与Ruby中绑定对象进行交互的唯一方法吗?

Wal*_*ndt 17 ruby scope eval

我对Ruby很陌生,到目前为止,弄清楚如何使用"绑定"对象是我最大的痛点之一.如果我正确阅读文档,它们几乎完全不透明.要访问绑定对象内的作用域,您必须拥有一个Ruby代码字符串并使用绑定来评估它.

也许我只是来自不同学校的纯粹主义者,但一般来说,我对基于字符串的'eval'结构过敏.在给定绑定对象的情况下,是否有任何方法可以安全地执行以下任何操作:

  1. 在绑定表示的上下文中列出范围中的标识符,或检索内容的哈希值.
  2. 将绑定中的局部变量的值设置为等于外部上下文中某个局部变量的值.理想情况下,即使值是对象引用,文件句柄或某些其他复杂实体,这通常也可以正常工作.
  3. (扩展2 :)给定一个哈希,在每个条目的绑定中设置本地.
  4. 更好的是,给定哈希构建与基本语言构造和范围中的哈希中的名称绑定.

基本上,我想知道哪些是可能的,以及如何完成那些.我想每个人的解决方案都是相当密切相关的,这就是为什么我把所有这些都放在一个问题中.

或者,有没有办法在绑定的上下文中解析已经解析过的代码,类似于Perl的eval BLOCK语法?

Wal*_*ndt 8

在搜索更多内容时,我找到了至少部分问题的答案:

基于:http://wikis.onestepback.org/index.cgi/Tech/Ruby/RubyBindings.rdoc/style/print

其余的是来自Jim Shubert的有用指针之后的实验.

  1. 这可以通过以下方式实现eval-ing local_variables,instance_variablesglobal_variables里面的约束力.
  2. 如下所述,给予你可以做一些事情var_name,new_val,my_binding(语法可能是不完美的或可改善,随时在评论建议.另外,我无法得到的代码格式化到列表里面工作,如何做到这一点也将建议实施.)
  3. 您可以直接使用(2)并循环哈希来执行此操作.
  4. 请参阅下面的第二个代码块.我的想法是从TOPLEVEL_BINDING开始,我认为通常只包括全局变量.

这确实涉及使用字符串eval.但是,没有变量值会扩展到所涉及的字符串中,因此如果按照描述使用它应该是相当安全的,并且应该能够"传入"复杂的变量值.

另请注意,始终可以eval var_name, my_binding获取变量的值.请注意,在所有这些用途中,变量的名称对于eval是安全的至关重要,因此理想情况下它根本不应来自任何类型的用户输入.

设置一个变量里面绑定给定的var_name,new_val,my_binding:

# the assignment to nil in the eval coerces the variable into existence at the outer scope
setter = eval "#{var_name} = nil; lambda { |v| #{var_name} = v }", my_binding
setter.call(new_val)
Run Code Online (Sandbox Code Playgroud)

建立"定制"绑定:

my_binding = eval "lambda { binding }", TOPLEVEL_BINDING # build a nearly-empty binding
# set_in_binding is based on the above snippet
vars_to_include.each { |var_name, new_val| set_in_binding(var_name, new_val, my_binding) }
Run Code Online (Sandbox Code Playgroud)

  • 接受这个,但如果有人知道如何避免使用字符串评估这些东西,请提供您的知识. (3认同)