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

use*_*188 2 ruby

假设我有一个w_data哈希

 {"latitude"=>"40.695", "air_temperature"=>"-10", "longitude"=>"-96.854", "datetime"=>"2014-01-01 02:55:00"}
Run Code Online (Sandbox Code Playgroud)

我希望通过w_data.latitude而不是获取它的价值w_data["latitude"]

怎么做?

Chr*_*ald 8

我要说的是不要使用OpenStruct,因为每次创建一个新的时都会使用方法缓存.

相反,考虑像hashie-mash这样的gem ,或者滚动你自己的hash- like :

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"
Run Code Online (Sandbox Code Playgroud)

定制解决方案

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"}
Run Code Online (Sandbox Code Playgroud)


Jai*_*yer 5

如果您想要一个纯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
Run Code Online (Sandbox Code Playgroud)

现在,每个哈希都具有此功能。

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

hash.fifteen = 15
hash[:fifteen]  #=> 15
hash.fifteen  #=> 15
Run Code Online (Sandbox Code Playgroud)

method_missing在每个Ruby类中都可用,以捕获对尚未存在的方法的尝试调用。我已经在这里将其转为博客文章(带有交互式Codewars kata):

http://www.rubycuts.com/kata-javascript-object