0

プロパティにアクセスし、そのプロパティにデータがない場合に、RESTAPIから動的にデータをロードするモデルがあります。

class Issue
  attr_accessor :ticket_title, :priority, :description
  @ticket_title
  @priority
  @description

  def priority
    if !@priority.empty?
      updateProperties()
    end
    @priority
  end
  def description
    if !@description.empty?
      updateProperties()
    end
    @description
  end
  def ticket_title
    if !@ticket_title.empty?
      updateProperties()
    end
    @ticket_title
  end

  def updateProperties
    # loads all data from REST API
  end

  def initialize (hsh = {})
      hsh.each { |key, value|
        self.instance_variable_set("@#{key}", value) 
      }
  end

end

2つの問題があります:

  1. モデルをで初期化する場合RedmineIssue.new :ticket_title => 'test'、モデルを呼び出したくupdatePropertiesありませんが、どういうわけかそうします。
  2. 関数を魔法のように宣言する方法はありますか?つまり、実際の関数がない場合は、メタ関数を実行してみてください。
4

2 に答える 2

3

メソッドを動的に追加するには、について読む必要がありますmethod_missing
それのいくつかの側面を説明する良い記事。
http://www.trottercashion.com/2011/02/08/rubys-define_method-method_missing-and-instance_eval.html

于 2012-07-20T17:00:33.580 に答える
1

さて、ここに「魔法」のための何かがあります。あなたのクラスで、get_whateverthekeyis(愚かな例、私が知っている)という名前のメソッドを介してハッシュの任意の部分を取得できるようにしたい場合は、次を使用しますmethod_missing

class Foo
  def initialize
    @h = {}
  end
  def method_missing(name, *args, &block)
    if(name =~ /\Aget_(.+)\Z/)
      #Name is valid
      sig_class.class_exec($1) do |n|
        define_method("get_"+n) {@h[n]}
      end

      @h[$1]
    elsif(name =~ /\Aset_(.+)\Z/)
      #Name is valid
      sig_class.class_exec($1) do |n|
        define_method("set_"+n) {|v| @h[n]=v}
      end

      @h[$1] = args[0]
    else
      super
    end
  end
  private
  def sig_class
    class << self
      self
    end
  end
end

メソッドが定義されていない場合は、に移動しmethod_missingます。その場合、method_missing要求された操作をハッシュで実行し、次にメソッドを動的に定義します。これにより、次回は直接メソッド呼び出しになります。つまり、メソッドが既に存在するため、はるかに効率的です。これはmethod_missing、Ruby独自のOpenStructで使用されているものと多少似ています。

于 2012-07-20T17:06:12.480 に答える