2

Every example I have found of the setter= syntax is very simple, ie;

def name=(value)
  @name = value
end

Can you do something more complex with this syntax? In particular, can you use it without having a corresponding instance variable? Can it be private? Can you do some sort of validation?

I am writing a Rails Controller that can be extended to give basic CRUD functionality to a model that is routed as a resource. It uses a class_attribute to set the name of the Model it will be controlling, and it creates an instance variable based on the name of the Model. It looks something like this;

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

With the above code structure I get a NoMethodError in the View because the View has a Nil instance variable. Using logger.debug I can trace the stack all the way to resource = ..., but resource= is not being called.

If I drop the sugar and useset_resource(value) everything works fine. Am I asking too much from setter= syntax, or is there some other problem I am missing?

4

2 回答 2

1
  • 你可以在没有相应实例变量的情况下使用它吗?

    是的。将其分配给具有任何名称的实例变量。

  • 可以私信吗?

    是和否。您可以定义表单的私有方法foo=,但您永远无法以普通方式调用它(即,不使用send或添加括号)。当表达式在对局部变量的引用/赋值和方法调用之间有歧义时,它将被解释为对局部变量的引用/赋值。这种类型的 Setter 方法总是需要一个显式的接收器。这也是你得到错误的原因。未调用 setter 方法,因为您没有显式编写接收器。

  • 你能做一些验证吗?

    是的。在实例变量赋值之前放置任何验证代码。

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

以 结尾的方法=具有某些特定性,使它们特别适合二传手。这些是:

  • 他们期望 1 个参数
  • 他们总是自动返回这个参数作为他们的返回值。

但是没有规则说它们必须用于二传手。如果人们发现他们的行为有另一种用途,那么可以在其中放入什么代码是没有限制的。

于 2013-09-18T16:39:50.483 回答