Ruby setter=未调用的方法
我发现的每个setter=语法示例都非常简单,即Ruby setter=未调用的方法,ruby,ruby-on-rails-3,Ruby,Ruby On Rails 3,我发现的每个setter=语法示例都非常简单,即 def name=(value) @name = value end 你能用这个语法做一些更复杂的事情吗?特别是,您可以在没有相应实例变量的情况下使用它吗?可以是私人的吗?你能做些验证吗 我正在编写一个Rails控制器,可以对其进行扩展,为作为资源路由的模型提供基本的CRUD功能。它使用class_属性设置要控制的模型的名称,并基于模型的名称创建实例变量。它看起来像这样 class ResourceController class_at
def name=(value)
@name = value
end
你能用这个语法做一些更复杂的事情吗?特别是,您可以在没有相应实例变量的情况下使用它吗?可以是私人的吗?你能做些验证吗
我正在编写一个Rails控制器,可以对其进行扩展,为作为资源路由的模型提供基本的CRUD功能。它使用class_属性设置要控制的模型的名称,并基于模型的名称创建实例变量。它看起来像这样
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
,因为视图有一个Nil实例变量。使用logger.debug
我可以一直跟踪堆栈到resource=…
,但是没有调用resource=
如果我放下糖,使用设置资源(值)
一切正常。我是对setter=语法要求太高了,还是缺少了其他问题?- 您可以在没有相应实例变量的情况下使用它吗 对。将其分配给具有任意名称的实例变量
- 可以是私人的吗
是和否。您可以定义一个私有方法,其形式为
,但您永远无法用普通方式调用它(即,不使用foo=
或添加括号)。当表达式在对局部变量的引用/赋值和方法调用之间不明确时,它将被解释为对局部变量的引用/赋值。这种Setter方法总是需要一个显式接收器。这也是你出错的原因。没有调用setter方法,因为您没有显式地编写接收方send
- 你能做些验证吗 对。将任何验证代码放在实例变量赋值之前
=
结尾的方法有一定的特殊性,使它们特别适合设置者。这些是:
- 他们期望有一个论点
- 它们总是自动将此参数作为返回值返回
但并没有规定必须将它们用于二传手。如果一个人发现自己的行为有其他用途,那么可以将哪些代码放入其中就没有限制。这很有意义。非常感谢。还有一个问题,您说
.send
是调用该方法的唯一方法,但是从同一类中的实例方法内部,为什么self.resource=
不起作用?或者,假设方法是受保护的而不是私有的,为什么super.resource=
不能在扩展类中工作?@BorisStitnicky我想你是对的。我错过了。在答案中添加了这一点。@user2754741我不明白您为什么要询问self.resource=
。我以为你想让方法保密。如果它是受保护的,那么我认为super.resource=
会起作用。我对private的理解是,只能从定义它的类中调用它,但根据您的回答,即使是从定义类中调用它,也需要显式的接收者。从类中的实例方法来看,self
不是显式的接收者吗?当您在没有显式接收器的情况下调用方法时,self
不是隐含接收器吗?“它需要显式接收器”=>不,它不能有显式接收器。要知道,一个明显的行为是将任何类设置为状态机。
def something=( arg )
# do anything
end