0

我创建了一个类,我有一些恒定的哈希值。我想输入Myclass.myhash.hashkey并显示哈希值。现在我已经创建了一个类似的行为,method_missing但我必须初始化对象,所以我称之为它Myclass.new.myhash.hashkey并且它可以工作。到目前为止,这是我的代码:

class Myclass
  def initialize
    @attributes = []
  end

  def method_missing(name, *args)
    @attributes << name
    if @attributes.length == 2
      eval("#{@attributes.first.upcase}[:#{@attributes.last.downcase}]")
    else
      self
    end
  end

  MYHASH = {
    id: 1,
    description: "A nice hash",
    hashkey: "hash key"
  }
end

我怎么能在没有初始化的情况下做到这一点,new所以它不会MyClass每次都创建一个对象?

更新: 第一个问题由 toro2k 解释,但我不知道是否使用它我可以有我的第二个问题的行为......

问题 2 我的类中有很多 openstruct,如何动态地将它们定义为类方法,而无需每次都添加如下内容:

  def self.myhash
    MYHASH
  end   
4

2 回答 2

2

您可以使用OpenStruct对象而不是Hash

class MyClass
  MYHASH = OpenStruct.new(id: 1, 
                          description: 'A nice Ostruct', 
                          hashkey: 'hash key')
  def self.myhash
    MYHASH
  end      
end

MyClass.myhash.id # => 1
MyClass.myhash.description # => "A nice Ostruct"
MyClass.myhash.foo # => nil

更新您可以像这样用类实例变量替换常量:

class MyClass
  def self.myhash
    @myhash ||= OpenStruct(id: ...)
  end
end

MyClass.myhash.id

或者您可以使用类变量和cattr_reader

class MyClass
  cattr_reader :myhash
  @@myhash = OpenStruct(id: ...)
end

MyClass.myhash.id

或者您可以摆脱该myhash方法并直接访问常量:

class MyClass
  MYHASH = OpenStruct(id: ...)
end

MyClass::MYHASH.id
于 2013-05-23T09:10:45.147 回答
1

我终于也为我的第二个问题找到了解决方案:

  class << self
    Myclass.constants.each do |constant|
      define_method(constant.to_s.downcase) do
        eval("#{constant}")
      end
    end
  end

在我定义了所有的 openstruct 变量之后,我只需在类的末尾添加它即可工作。

于 2013-05-23T11:03:05.350 回答