ruby attr_accessor 的奇怪行为
Strange behave of ruby attr_accessor
我有这段代码:
class CallMe
attr_accessor :a, :b, :c
def self.start(*args)
self.new(*args).get_answer
end
def initialize(a,b,c)
@a = a
@b = b
@c = c
end
def get_answer
if c
b = nil
else
return b
end
end
end
answer = CallMe.start(1,2,nil)
为什么当我 运行 在 irb 中我总是得到 answer = nil
即使逻辑情况是得到 b 值 2
那是因为在 if
语句的上下文中,您实际上在键入 b = nil
时重新定义了 b
。对于 Ruby,不清楚是要调用对象的方法 :b
还是要创建一个新变量 b
。在这种情况下,优先级总是从全局到最近的上下文,在这种情况下 - 到 if
块内的上下文。
如果你愿意改变
if c
b = nil
else
return b
end
# to
if c
# b = nil
# or
self.b = nil
else
return b
您会发现它按预期工作。
可变提升 效果在多种语言中使用。对于 Ruby,它在 official documentation:
中进行了描述
The local variable is created when the parser encounters the assignment, not when the assignment occurs
因此,get_answer
方法创建 local 变量 b
而不管 c
的值。 和在创建时将局部变量b
赋值给nil
。然后 get_answer
returns 局部变量 b
总是 nil
.
正确方法:
def get_answer
c ? self.b = nil : b
end
我有这段代码:
class CallMe
attr_accessor :a, :b, :c
def self.start(*args)
self.new(*args).get_answer
end
def initialize(a,b,c)
@a = a
@b = b
@c = c
end
def get_answer
if c
b = nil
else
return b
end
end
end
answer = CallMe.start(1,2,nil)
为什么当我 运行 在 irb 中我总是得到 answer = nil
即使逻辑情况是得到 b 值 2
那是因为在 if
语句的上下文中,您实际上在键入 b = nil
时重新定义了 b
。对于 Ruby,不清楚是要调用对象的方法 :b
还是要创建一个新变量 b
。在这种情况下,优先级总是从全局到最近的上下文,在这种情况下 - 到 if
块内的上下文。
如果你愿意改变
if c
b = nil
else
return b
end
# to
if c
# b = nil
# or
self.b = nil
else
return b
您会发现它按预期工作。
可变提升 效果在多种语言中使用。对于 Ruby,它在 official documentation:
中进行了描述The local variable is created when the parser encounters the assignment, not when the assignment occurs
因此,get_answer
方法创建 local 变量 b
而不管 c
的值。 和在创建时将局部变量b
赋值给nil
。然后 get_answer
returns 局部变量 b
总是 nil
.
正确方法:
def get_answer
c ? self.b = nil : b
end