加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – 创建一个Binding,它的唯一变量是来自Hash的键

发布时间:2020-12-17 02:06:18 所属栏目:百科 来源:网络整理
导读:我知道我可以使用ostruct从Hash创建一个Binding,如下所示: require 'ostruct'not_in_locals = "we don't want this"locals = {a: 1,b: 2}my_binding = OpenStruct.new(locals).instance_eval { binding }p my_bindingp eval("a",my_binding) #good,we want
我知道我可以使用ostruct从Hash创建一个Binding,如下所示:

require 'ostruct'

not_in_locals = "we don't want this"
locals = {a: 1,b: 2}
my_binding = OpenStruct.new(locals).instance_eval { binding }
p my_binding
p eval("a",my_binding) #good,we want this
p eval("b",we want this
p eval("not_in_locals",my_binding) #bad,don't want it to access this,but it can

您可以在此处查看输出,该输出确认代码中的注释:https://eval.in/132925

正如您所看到的,问题是Binding还绑定了本地上下文中不在Hash中的变量.我想要一个从Hash创建Binding对象的方法,除了来自Hash的键之外什么也没有绑定.

解决方法

你可以尝试这样的事情.它绕过了一个直接的eval()调用,用于辅助类方法调用.辅助类方法称为evaluate(),但它仅适用于非常简单的值(目前仅测试的字符串和整数)并依赖于inspect().

但是,如果您正在处理的值的类型是提前知道的,则可以将其修改为可行.

class HashBinding
  def initialize(hash)
    @hash = hash
  end

  def evaluate(str)
    binding_code = @hash.to_a.map do |k,v|
      "#{k} = #{v.inspect};"
    end.join(" ")
    eval "#{binding_code}; #{str}"
  end
end

not_in_hash = 'I am not in the hash'
hash = { :foo => 'foo value',:baz => 42}
hash_binding = HashBinding.new(hash)

hash_binding.evaluate('puts "foo = #{foo}"')
hash_binding.evaluate('puts "baz = #{baz}"')
hash_binding.evaluate('puts "not_in_hash = #{not_in_hash}"')

输出是:

ruby binding_of_hash.rb
foo = foo value
baz = 42
binding_of_hash.rb:10:in `eval': undefined local variable or method `not_in_hash' for #<HashBinding:0x007fcc0b9ec1e8> (NameError)
    from binding_of_hash.rb:10:in `eval'
    from binding_of_hash.rb:10:in `evaluate'
    from binding_of_hash.rb:20:in `<main>'

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读