【问题标题】:best way to access a hash inside a Ruby module在 Ruby 模块中访问哈希的最佳方法
【发布时间】:2021-04-17 20:21:55
【问题描述】:

我正在使用一个模块来封装一组变量以及与这些变量相关的方法。这些变量之一是应该使用模块方法更新的哈希。我通过以下代码实现了这个目标:

module MyModule
  @hash_a = {
        key1: "value1",
        key2: "value2"
  }
  def self.hash_a_set(key,value)
    @hash_a[key]=value
  end
  def self.hash_a_get(key)
    return @hash_a[key]
  end
end

MyModule.hash_a_get(:key1) # "value1" 
MyModule.hash_a_set(:key1,2) 
MyModule.hash_a_get(:key1) # 2 

即使这很有效,使用那些 setter 和 getter 方法感觉也不对。有没有办法按如下方式访问它们(或任何其他类似于哈希语法的方式)?

MyModule.hash_a[:key1] # "value1" 
MyModule.hash_a[:key1]=2 
MyModule.hash_a[:key1] # 2 

谢谢

【问题讨论】:

  • 也许这应该是一个带有访问器的对象。
  • 你可以定义self.[]self.[]=(val)然后你可以直接调用MyModule[:key1]或者MyModule[:key1]=2

标签: ruby module


【解决方案1】:

如果你有一个返回@hash_a 的方法hash_a,那么是的,第二种形式很简单:

module MyModule
  @hash_a = {
        key1: "value1",
        key2: "value2"
  }
  def self.hash_a
    @hash_a
  end
end

请注意,Ruby 试图避免使用 getset 方法,因此如果您可以将其表达为 xx= 之类的东西,那么通常效果会更好。在这种情况下,如果直接暴露 Hash 是可以接受的,那就做最简单的事情。

【讨论】:

  • 老实说“……只做最简单的事情”是一个非官方的红宝石座右铭。可能紧随其后的是“有 12 种方法可以做任何事情”和“足够的绳子射中自己的脚”
  • 如果我做对了,我有一个概念问题。 setter 方法用于将一个对象替换为另一个对象。例如,指令 x.a=12 创建类整数的对象 12 并将其放入实例变量“a”中。我试图使用 setter 替换存储在实例变量中的哈希的内容。这是没有意义的,因为 setter 是一种旨在替换对象而不是查看或替换其中的东西的方法。
  • 另一方面,getter 检索存储在实例变量中的对象(全部)。就像隐藏在宫廷后面(物体内部)的汽车。 getter 检索整个对象。如果这个物体是一辆汽车,你可以驾驶它,如果它是一个蛋糕,你可以吃它。如果这个对象是一个散列,就像本例一样,你可以用通常的方式访问散列的内容。
  • 在 Ruby 中,“一切都是对象”原则经常出现,尤其是当 Hash 中的键可以是任意对象时。不过,x.a 不会创建实例变量。方法a= 需要提前定义,否则会调用method_missingOpenStruct 可以做到这一点,但它使用哈希在内部存储这些,而不是变量本身。您始终可以拥有attr_accessor :a,它允许读写访问,这在 Ruby 术语中意味着它生成方法 aa=
猜你喜欢
  • 2019-12-07
  • 1970-01-01
  • 2014-04-09
  • 1970-01-01
  • 2010-10-21
  • 1970-01-01
  • 1970-01-01
  • 2010-09-07
  • 2013-04-18
相关资源
最近更新 更多