Ruby将散列内的值转换为局部变量

kak*_*bei 17 ruby

说我有这个哈希:

entry = {"director"=>"Chris Nolan", "prducer"=>"Sum Duk", "writer"=>"Saad Bakk"}
Run Code Online (Sandbox Code Playgroud)

我想将每个键提取到自己的局部变量中,并带有相关的值:

director = "Chris Nolan"
producer = "Sum Duk"
...
Run Code Online (Sandbox Code Playgroud)

通过使用循环而不是:

director = entry["director"]
Run Code Online (Sandbox Code Playgroud)

由于有很多值,我不想单独进行.

我发现这几乎完全有效,除了它创建一个实例变量,我想要一个局部变量,但local_variable_set由于某种原因不存在.

entry.each_pair { |k, v| instance_variable_set("@#{k}", v) }
Run Code Online (Sandbox Code Playgroud)

有解决方案吗?或者失败了,一种方法将实例变量转换为本地变量并删除实例变量而不逐一进行?

ant*_*ome 6

选项1

除了有趣之外,我不能推荐这个,但它主要具有以下效果:

entry.each |k, v|
  singleton_class.send(:attr_accessor, k)
  send("#{k}=", v)
end

director                        # => "Chris Nolan"
self.director = "Wes Anderson"  # Unfortunately, must use self for assignment
director                        # => "Wes Anderson"
Run Code Online (Sandbox Code Playgroud)

它不是创建局部变量,而是在当前对象的单例类上定义acccessor方法,您可以将它们称为局部变量.

为了使它们更"本地",您可以使用singleton_class.remove_method它们来完成它们后删除这些方法.您甚至可以尝试使用相同的名称对任何现有的单例类方法进行别名,然后再将它们还原.

选项2

这是我在实际代码中使用的东西.它需要Ruby On Rails附带的ActiveSupport gem,但也可以单独使用.

director, producer, writer = entry.values_at('director', 'producer', 'writer')
Run Code Online (Sandbox Code Playgroud)

不幸的是,它需要输入两次变量名,而不是你要求的零次.如果您确定哈希值中的值的顺序,您可以写:

director, producer, writer = entry.values  # Not so good, IMO.
Run Code Online (Sandbox Code Playgroud)

我对这个版本感到不安,因为现在创建哈希的代码有一个非显而易见的责任,以确保哈希按特定顺序.

注意

如果您的目标只是减少键入,那么这种方法每个变量访问只需要两个字符,而不是真正的局部变量:

e = OpenStruct.new(entry)
e.director     # => "Chris Nolan"
Run Code Online (Sandbox Code Playgroud)

  • 选项 2 – `values_at` – 是一个不错的选择。 (2认同)

Mur*_*foX 4

由于变量范围的原因,您无法创建局部变量。
如果在块内创建局部变量,则该变量只能在块本身内部访问。
请参阅此问题以获取更多信息。
在 Ruby 中动态设置局部变量