如果 ruby 将您在最后一条语句中的赋值解释为对 的赋值self
,那么您将无法设置局部变量。
它的方式让解释器处理起来没有歧义:没有self
的赋值总是局部变量,对 self 的赋值总是试图在对象上使用编写器。
如果反过来
解释器必须查找上下文编写器方法并通过编写器分配它(如果有的话),这几乎肯定会对性能产生负面影响
class A
attr_writer :foo
end
A.new.instance_eval do
# for each of these assignments, the interpreter has to look up if there's
# a writer method defined
foo = 'bar'
bar = 'baz'
fib = 'buz'
end
在分配局部变量之前,程序员还有一项相当愚蠢的任务是找出他所在上下文的每个 setter 方法,以确保他不会无意中使用 setter。
class C
attr_writer :something
end
class B < C
attr_writer :foo
end
class A < B
attr_writer :bar
end
A.new.instance_eval
something = 'something'
#you just (almost certainly with no intention) assigned a value to an attribute
end
另外,你的问题是:
即使在有问题的表达式之前没有分配具有相同名称的局部变量时,如果没有显式接收器也不能使用 setter 方法:
如果反过来,则不能在相关表达式之前分配具有相同名称的局部变量,因为分配将使用 setter(如本答案第一段所述)
关于实现/访问属性方法使用的变量:Getter 和 Setter 使用实例变量。因此,例如attr_accessor
实际上定义了这样的东西:
def foo
@foo
end
def foo=(data)
@foo = data
end
那么,属性被声明为实例变量而不是局部变量,为什么程序员可以像局部变量一样赋值呢?这会留下错误的印象,即您可以通过分配局部变量来分配对象的实例变量。如果 ruby 会这样做,那几乎肯定会导致严重的内存管理问题。简而言之:foo = 'bar'
并且@foo = 'bar'
不一样,并且正是因为attr
方法 use @foo = 'bar'
,您不能通过 using 调用它们foo = 'bar'
。