我发现的setter =语法的每个例子都非常简单,即;
def name=(value)
@name = value
end
使用这种语法可以做一些更复杂的事情吗?特别是,您可以在没有相应实例变量的情况下使用它吗?它可以是私人的吗?你能做某种验证吗?
我正在编写一个Rails控制器,可以对其进行扩展,以便为作为资源路由的模型提供基本的CRUD功能。它使用class_attribute来设置它将控制的Model的名称,并根据Model的名称创建一个实例变量。它看起来像这样;
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
使用上面的代码结构,我在View中得到NoMethodError
,因为View有一个Nil实例变量。使用logger.debug
我可以跟踪堆栈一直到resource = ...
,但resource=
没有被调用。
如果我放糖并使用set_resource(value)
一切正常。我是不是从setter =语法中问了太多,还是我还缺少其他一些问题?
答案 0 :(得分:1)
您可以在没有相应实例变量的情况下使用它吗?
是。将其分配给具有任何名称的实例变量。
可以私密吗?
是和否。您可以定义foo=
形式的私有方法。 ,但您永远无法以普通方式调用它(即,不使用 send
或添加括号)。当表达式在引用/赋值给局部变量和方法调用之间不明确时,它将被解释为对局部变量的引用/赋值。这种Setter方法总是需要一个明确的接收器。这也是你得到错误的原因。未调用setter方法,因为您没有显式写入接收器。
你能做某种验证吗?
是。在实例变量赋值之前放置任何验证代码。
答案 1 :(得分:0)
def something=( arg )
# do anything
end
以=
结尾的方法具有某些细节,使它们特别适合setter。这些是:
但没有规则说他们必须用于制定者。如果有人发现他们的行为有其他用途,那么可以在其中放入什么代码没有限制。