【问题标题】:Interchanging hash keys and local variable names in Ruby [duplicate]在Ruby中交换哈希键和局部变量名[重复]
【发布时间】:2012-06-23 22:22:21
【问题描述】:

可能重复:
Is there a Ruby equivalent to PHP's extract?

有没有办法获取 Ruby 哈希,例如:

myhash = {a: 12, b:24, c:36}

并将其转换为一组局部变量(显然,没有手动进行赋值)?结果应该就像我执行了语句一样:

a = 12
b = 24
c = 36

同样,我可以使用一组已定义的局部变量并生成一个哈希,其中键是变量名,值是变量值(同样,没有字面写出哈希)?我以前从未见过这样的事情,所以我猜答案是否定的,但它会很好......

【问题讨论】:

  • 无论您尝试做什么,几乎肯定有更好的方法。您能否提供更多信息,以便我们提出不同的解决方案?
  • @JoshuaCheek 我发现自己相当频繁地将中等大小的散列作为参数传递。必须一直通过哈希语法访问存储在这些哈希中的值既麻烦又臃肿——我想我可以在我的方法中“解包”(或提取)哈希,做我打算做的任何操作,然后在退货时重新包装。
  • 我怀疑答案是拥抱 OO。如果哈希是选项,请将它们拉出并设置在 ivars 上。如果您实际上是在操作它们,那么很有可能您应该使用对象而不是哈希(而不是在哈希中保存数据,而是对象保存它。而不是操作哈希的数据,您告诉对象操作它自己的数据)。不看更多代码很难给出更好的建议。
  • 这对我有用(但它很老套): myhash = {a: 12, b: 24, c: 36} myhash.each do |k, v| Kernel.send(:define_method, k, Proc.new {v}) end
  • 如果您不想通过散列访问方法参数,那么也许您一开始就不应该将它们作为散列传递?

标签: ruby variables hash


【解决方案1】:

您可能已经知道这一点,但为了记录:如果您愿意创建实例变量而不是本地变量,那么此函数将起作用:

def f x
  x.each do |k, v|
    instance_variable_set "@#{k}", v
  end
end

f :abc => 123, 'def' => 456

> @abc
=> 123 
> @def
=> 456 

【讨论】:

    【解决方案2】:

    你可以用Kernel.eval做很多这样的事情:

    a = 1; b = 2; c = 3
    
    local_variables.grep(/^[a-z]\w*/)
    => ["a", "b", "c"]
    
    # Map local variables to hash
    @h = Hash[local_variables.grep(/^[a-z]\w*/).map { |var| [var, eval(var)] }]     
    => {"a"=>1, "b"=>2, "c"=>3}
    
    # Map hash to local variables
    @b = binding
    @h.each { |k,v| eval("#{k}_new = #{v + 100}", @b) }
    
    local_variables.grep(/^[a-z]\w*/)
    => ["a", "b", "c", "a_new", "b_new", "c_new"]
    
    [a_new, b_new, c_new]
    => [101, 102, 103]
    

    【讨论】:

    • "#{usual_code_injection_warning}"
    • 这在 Ruby 1.9 中不起作用,因为在 eval 中声明的任何局部变量的范围仅限于 eval 本身。
    • @AndrewMarshall 哇,我不知道。知道为什么吗?似乎绑定可以用来调整范围,就像在 1.8 中一样。奇怪的设计决定:-(
    • @Casper 可能是安全性——毕竟这不是一个好主意。 Here's a brief reply by Matz about it.
    • @AndrewMarshall 好的,谢谢。然而,作为一名程序员,我不太喜欢这种强制手持(这在这里没有多大帮助:))。但是好的..没有多少情况下你真的需要做这样的事情。开始想知道 IRB 在 1.9 中是如何工作的。如果没有此功能,如何构建 REPL。嗯。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    • 2013-08-26
    • 2013-07-20
    • 1970-01-01
    • 2014-07-02
    • 2011-12-28
    相关资源
    最近更新 更多