我对Ruby很陌生,到目前为止,弄清楚如何使用"绑定"对象是我最大的痛点之一.如果我正确阅读文档,它们几乎完全不透明.要访问绑定对象内的作用域,您必须拥有一个Ruby代码字符串并使用绑定来评估它.
也许我只是来自不同学校的纯粹主义者,但一般来说,我对基于字符串的'eval'结构过敏.在给定绑定对象的情况下,是否有任何方法可以安全地执行以下任何操作:
基本上,我想知道哪些是可能的,以及如何完成那些.我想每个人的解决方案都是相当密切相关的,这就是为什么我把所有这些都放在一个问题中.
或者,有没有办法在绑定的上下文中解析已经解析过的代码,类似于Perl的eval BLOCK语法?
在搜索更多内容时,我找到了至少部分问题的答案:
基于:http://wikis.onestepback.org/index.cgi/Tech/Ruby/RubyBindings.rdoc/style/print
其余的是来自Jim Shubert的有用指针之后的实验.
eval-ing local_variables,instance_variables和global_variables里面的约束力.var_name,new_val,my_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)