ruby 如何访问哈希的键作为对象属性

h4cxqtbf  于 2023-05-22  发布在  Ruby
关注(0)|答案(4)|浏览(182)

假设我有一个w_data哈希

{"latitude"=>"40.695", "air_temperature"=>"-10", "longitude"=>"-96.854", "datetime"=>"2014-01-01 02:55:00"}

我想通过w_data.latitude而不是w_data["latitude"]访问它的值
怎么做?

qltillow

qltillow1#

我会说 * 不要 * 使用OpenStruct,因为它是nukes the method cache every time you create a new one
相反,考虑像hashie-mash这样的gem,或者使用自己的hash-alike:
Hashie::Mash

hsh = Hashie::Mash.new("latitude"=>"40.695", "air_temperature"=>"-10", "longitude"=>"-96.854", "datetime"=>"2014-01-01 02:55:00")
hsh.latitude
 => "40.695"

定制解决方案:

class AccessorHash < Hash
  def method_missing(method, *args)
    s_method = method.to_s
    if s_method.match(/=$/) && args.length == 1
      self[s_method.chomp("=")] = args[0]
    elsif args.empty? && key?(s_method)
      self.fetch(s_method)
    elsif args.empty? && key?(method)
      self.fetch(method)
    else
      super
    end
  end
end

hsh = AccessorHash.new("latitude"=>"40.695", "air_temperature"=>"-10", "longitude"=>"-96.854", "datetime"=>"2014-01-01 02:55:00")
hsh.latitude # => "40.695"
hsh.air_temperature = "16"
hsh => # {"latitude"=>"40.695", "air_temperature"=>"16", "longitude"=>"-96.854", "datetime"=>"2014-01-01 02:55:00"}
91zkwejq

91zkwejq2#

如果你想要一个纯Ruby的解决方案,只需打开Hash类并升级method_missing方法!

class Hash
  def method_missing method_name, *args, &block
    return self[method_name] if has_key?(method_name)
    return self[$1.to_sym] = args[0] if method_name.to_s =~ /^(.*)=$/

    super
  end
end

现在,每个哈希都有这个能力。

hash = {:five => 5, :ten => 10}
hash[:five]  #=> 5
hash.five  #=> 5

hash.fifteen = 15
hash[:fifteen]  #=> 15
hash.fifteen  #=> 15

method_missing在每个Ruby类中都可用,用于捕获对不存在的方法的尝试调用。我已经把它变成了一篇博客文章(带有交互式Codewars kata):
http://www.rubycuts.com/kata-javascript-object

r7xajy2e

r7xajy2e3#

将hash转换为OpenStruct。这里:

require 'ostruct'
w_data = OpenStruct.new
hash = {"latitude"=>"40.695", "air_temperature"=>"-10", "longitude"=>"-96.854", "datetime"=>"2014-01-01 02:55:00"}
w_data.marshal_load(hash)
w_data.longitude
#=> "-96.854"

另一个更简单的方法:

require 'ostruct'
hash = {"latitude"=>"40.695", "air_temperature"=>"-10", "longitude"=>"-96.854", "datetime"=>"2014-01-01 02:55:00"}
w_data = OpenStruct.new(hash)
w_data.longitude
#=> "-96.854"
6kkfgxo0

6kkfgxo04#

如果您正在使用Ruby on Rails,则可以利用ActiveSupport::OrderedOptions模块来访问哈希键作为属性。此模块扩展了常规散列的功能,允许您使用点表示法访问其键。
此外,您可以使用ActiveSupport::InheritableOptions通过向其传递现有哈希来创建新对象。你可以走了。
如示例所示:

h = ActiveSupport::InheritableOptions.new({ girl: 'Mary', boy: 'John' })
h.girl # => 'Mary'
h.boy

相关问题