在Ruby中与绑定对象交互的唯一方法是“eval”吗?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (17)

我对Ruby比较陌生,到目前为止,弄清楚如何使用“binding”对象是我最大的难题之一。如果我正确阅读文档,它们几乎完全不透明。要访问绑定对象内的作用域,必须有一串Ruby代码,并使用绑定对其进行评估。

给定一个绑定对象,是否有任何方法可以安全地执行以下任何操作:

  • 在绑定表示的上下文中列出范围内的标识符,或者检索内容的哈希。
  • 将绑定中的局部变量的值设置为等于外部上下文中某个局部变量的值。理想情况下,即使该值是对象引用,文件句柄或其他复杂实体,它也应该可以正常工作。
  • 给定一个散列,只用基本语言结构和散列中的名字构建一个绑定。

提问于
用户回答回答于

部分答案:

wikis.onestepback.org/index.cgi/Tech/Ruby/RubyBindings.rdoc/style/print

  • 这可以通过eval-ing 完成local_variablesinstance_variablesglobal_variables在绑定中完成。
  • 如下所述,给予你可以做一些事情var_namenew_valmy_binding(语法可能是不完美的或可改善,随时在评论建议。另外,我无法得到的代码格式化到列表里面工作,如何做到这一点也将建议被执行。)
  • 你可以直接采取(2)并循环散列来做到这一点。
  • 请参阅下面的第二个代码块。这个想法是从TOPLEVEL_BINDING开始的,我通常认为它只包含全局变量。

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

另外请注意,eval var_name, my_binding获取变量的值总是可能的。请注意,在所有这些用途中,变量的名称对于评估是安全的,这一点至关重要,因此它理想情况下不应该来自任何用户输入。

设置一个变量里面绑定给定的var_namenew_valmy_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)

建立一个“定制”的约束:

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) }
用户回答回答于

jim@linux-g64g:~> irb
irb(main):001:0> eval "self", TOPLEVEL_BINDING
=> main
irb(main):002:0> eval "instance_variables", TOPLEVEL_BINDING
=> []
irb(main):003:0> eval "methods", TOPLEVEL_BINDING
=> ["irb_kill", "inspect", "chws", "install_alias_method", ....

扫码关注云+社区