2

私が見つけた setter= 構文の例はすべて非常に単純です。

def name=(value)
  @name = value
end

この構文でもっと複雑なことはできますか? 特に、対応するインスタンス変数を持たずに使用できますか? プライベートでもいい?何らかの検証を行うことはできますか?

リソースとしてルーティングされるモデルに基本的な CRUD 機能を提供するために拡張できる Rails コントローラーを作成しています。class_attribute を使用して、制御するモデルの名前を設定し、モデルの名前に基づいてインスタンス変数を作成します。次のようになります。

class ResourceController
  class_attribute :model_class_name

  def new
    resource = self.model_class_name.new
  end

  protected
    def self.init_resource(options={})
      self.model_class_name = options[:model_class_name]
    end 

  private
    def resource
      instance_variable_get(resource_instance_var)
    end

    def resource=(value)
      instance_variable_set(resource_instance_var ,value)
    end

    def resource_instance_var 
      "@#{self.resource_class.name.underscore}".to_sym
    end
end

上記のコード構造NoMethodErrorでは、View に Nil インスタンス変数があるため、View で を取得します。I を使用するlogger.debugと、 までスタックをトレースできますが、呼び出されてresource = ...resource=ません。

砂糖を落として使うと、set_resource(value)すべてうまくいきます。私は setter= 構文からあまりにも多くを求めていますか、それとも私が見逃している他の問題がありますか?

4

2 に答える 2

1
  • 対応するインスタンス変数がなくても使用できますか?

    はい。任意の名前のインスタンス変数に割り当てます。

  • プライベートでもいい?

    はい、いいえ。フォームのプライベート メソッドを定義できますfoo=ですが、通常の方法 (つまり、括弧を使用または追加しない) で呼び出すことはできません。sendローカル変数への参照/代入とメソッド呼び出しのあいまいな式は、ローカル変数への参照/代入として解釈されます。この種のセッター メソッドには、常に明示的なレシーバーが必要です。それがエラーが発生した理由でもあります。レシーバーを明示的に記述していないため、setter メソッドは呼び出されませんでした。

  • 何らかの検証を行うことはできますか?

    はい。インスタンス変数の割り当ての前に、任意の検証コードを配置します。

于 2013-09-18T16:23:36.470 に答える
0
def something=( arg )
  # do anything
end

で終わるメソッドに=は特定の仕様があり、セッターに特に適しています。これらは:

  • 彼らは1つの引数を期待しています
  • この引数は、戻り値として常に自動的に返されます。

しかし、セッターに使用しなければならないというルールはありません。それらの動作の別の用途を見つけた場合、それらに入れることができるコードに制限はありません。

于 2013-09-18T16:39:50.483 に答える