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 番目の質問の動作ができるかどうかはわかりません...

質問 2 クラスに多くの openstructs があります。毎回次のようなものを追加せずに、それらをクラス メソッドとして動的に定義するにはどうすればよいですか。

  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

2番目の質問の解決策もついに見つけました:

  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 に答える