在Ruby中交换哈希键和局部变量名

4
有没有办法处理一个类似于以下 Ruby 哈希的东西:

可能有重复:
是否有 Ruby 等效于 PHP 的 extract 函数?

例如:

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

我需要将这个转换为一组本地变量(当然不能手动进行赋值)。结果应该就像我执行了以下语句一样:

a = 12
b = 24
c = 36

同样地,我能否使用一组定义好的本地变量创建一个哈希表,其中键是变量名,值是变量值(除了手动编写哈希表外)?我之前没有见过类似的操作,所以猜测答案是否定的,但这样做会很方便...

无论你想做什么,几乎肯定有更好的方法。您能提供更多信息,以便我们可以提供不同的解决方案吗? - Joshua Cheek
@JoshuaCheek 我经常发现自己需要传递中等大小的哈希作为参数。每次都通过哈希语法访问这些哈希中存储的值非常麻烦和臃肿 - 我想我可以在我的方法中“解包”(或提取)哈希,在完成所需操作后重新打包返回。 - Sean Mackesey
我认为答案是采用面向对象编程。如果哈希表是选项,则将它们提取出来并设置为实例变量。如果您实际上正在操作它们,那么很有可能应该使用对象而不是哈希表(对象保存数据而不是在哈希表中保存数据,您告诉对象操作自己的数据而不是操作哈希表的数据)。没有看到更多代码很难给出更好的建议。 - Joshua Cheek
这对我有效(但有点hacky):myhash = {a: 12, b: 24, c: 36}myhash.each do |k, v| Kernel.send(:define_method, k, Proc.new {v}) end - Oscar Del Ben
如果您不喜欢通过哈希访问方法参数,那么也许您一开始就不应该将它们作为哈希传递? - Lars Haugseth
2个回答

2

您可能已经知道,但为了记录:如果您愿意创建实例变量而不是局部变量,则此函数将起作用:

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

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

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

0

您可以使用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]

1
"#{usual_code_injection_warning}" - DigitalRoss
在 Ruby 1.9 中,这是行不通的,因为在 eval 中声明的任何局部变量的作用域仅限于 eval 本身。 - Andrew Marshall
@AndrewMarshall 哇,我不知道那个。你有什么想法吗?似乎绑定可以像1.8中一样用于调整范围。奇怪的设计决定 :-( - Casper
@Casper 可能是出于安全考虑——毕竟这不是一个很好的想法。这里是 Matz 的简短回复 - Andrew Marshall
@AndrewMarshall 好的,谢谢。然而作为一名程序员,我不太喜欢这种强制性的辅助(尽管这在这里帮助不是很大 :))。但好吧..很少有情况需要做任何这样的事情。开始想知道1.9中 IRB 的实际工作原理。没有这个功能你如何建立一个 REPL。嗯。 - Casper
有兴趣的人:这就是在1.9中irb的工作原理:@ irb_binding = eval(“def irb_binding; binding; end; irb_binding”)。所有eval调用都在irb_binding上下文中进行评估。这使得本地变量通过整个IRB会话保持在同一上下文中。 - Casper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接