2

正しい質問をしているかどうかさえわかりません。問題に間違ってアプローチしている可能性がありますが、基本的には次のような状況があります。

obj = get_user(params)
obj.profile => {:name => "John D", :age => 40, :sex => "male"} #Has to be of class Hash
obj.profile.name => "John D"
obj.profile[:name] => "John D"
obj.profile.job => nil

基本的に、これらの条件をすべて満たす必要がありますが、これにどのようにアプローチすればよいかわかりません (今日 Ruby を学習したばかりです)。

内部変数にアクセスするためのドット表記に注意してください。それ以外の場合は、プロファイルをシンボルのハッシュにするだけです。だから私は2つの方法を試しましたが、そこにたどり着くだけです

方法 1:プロファイルを OpenStruct にする

これにより、ドット表記を使用して名前、年齢、性別にアクセスできるようになり、キーが存在しない場合は自動的に nil が返されますが、obj.profileはHashではなくOpenStruct型です。

方法 2:プロファイルを独自のクラスにする

これにより、それらをインスタンス変数として設定し、存在しない場合はmethod_missingを使用して nil を返すことができます。しかし、私は再びobj.profileが正しいタイプ/クラスではないという問題に遭遇しました

足りないものはありますか?おそらく区別する方法はありますか

obj.profile
obj.profile.name

ゲッター関数で、ハッシュまたはその他のいずれかを返しますか?

プロファイルのカスタム クラスによって返されるものを変更して、代わりにハッシュを返すことはできますか?

obj.profile の get 関数でargsと **kwargs をチェックしようとしましたが、どちらも役に立たないようです

4

3 に答える 3

1

絶対にある必要がある場合Hash

require 'pp'

module JSHash
  refine Hash do
    def method_missing(name, *args, &block)
      if !args.empty? || block
        super(name, *args, &block)
      else
        self[name]
      end
    end
  end
end

using JSHash

profile = {:name => "John D", :age => 40, :sex => "male"}

pp profile.name    # "John D"
pp profile[:name]  # "John D"
pp profile.job     # nil
pp profile.class   # Hash

Hashただし、絶対に必要な場合を除き、 にならない方がよいでしょう:

require 'pp'

class Profile < Hash
  def initialize(hash)
    self.merge!(hash)
  end
  def method_missing(name, *args, &block)
    if !args.empty? || block
      super(name, *args, &block)
    else
      self[name]
    end
  end
end

profile = Profile.new({:name => "John D", :age => 40, :sex => "male"})

pp profile.name
pp profile[:name]
pp profile.job
于 2015-02-20T06:19:46.707 に答える
1

いくつかのハッシュ キーのみについては、次のようにシングルトン メソッドを簡単に定義できます。

def define_getters(hash)
  hash.instance_eval do
    def name
      get_val(__method__)
    end

    def job
      get_val(__method__)
    end

    def get_val(key)
      self[key.to_sym]
    end
  end
end

profile = person.profile #=> {name: "John Doe", age: 40, gender: "M"}
define_getters(profile)

person.profile.name #=> "John Doe"
person.profile.job #=> nil

変更された値も反映します (疑問がある場合):

person.profile[:name] = "Ralph Lauren"
person.profile.name #=> "Ralph Lauren"

このアプローチでは、 をオーバーライドしたりmethod_missing、 から継承した新しいクラスを作成しHashたり、クラスにモンキー パッチを適用したりする必要はありませんHash

ただし、メソッド呼び出しを介して未知のキーにアクセスしnil、エラーの代わりに返すことができるようにするには、method_missing.

于 2015-02-20T06:44:08.170 に答える