gpt4 book ai didi

ruby - 未执行的代码覆盖局部变量

转载 作者:太空宇宙 更新时间:2023-11-03 17:47:39 25 4
gpt4 key购买 nike

给定代码:

class Foo
attr_reader :bar

def initialize
@bar = "abc"
if false
bar = "123"
end
p bar
end
end

Foo.new

结果是

nil

为什么 p barinitialize 中打印 nil 而不是 abc

最佳答案

试试这个:

class Foo
attr_reader :bar
def initialize
p "instance methods defined in Foo: #{self.methods(false)}"
@bar = "abc"
p "defined? @bar: #{defined? @bar}"
p "bar: #{bar}"
p "defined? bar: #{defined? bar}"
if false
bar = "123"
end
p "defined? bar, 2nd time: #{defined? bar}"
p "bar.nil? = #{bar.nil?}"
p "self.bar = #{self.bar}"
p "instance methods defined in Foo: #{self.class.instance_methods(false)}"
end
end

Foo.new
"instance methods defined in Foo: [:bar]"
"defined? @bar: instance-variable"
"bar: abc"
"defined? bar: method"
"defined? bar, 2nd time: local-variable"
"bar.nil? = true"
"self.bar = abc"
"instance methods defined in Foo: [:bar]"

线条:

"defined? @bar: instance-variable"
"defined? bar: method"

说明@bar是实例变量,bar是实例方法,即创建的@bar的getter方法>attr_reader :bar。之前

if false
bar = "123"
end

被评估,Ruby 进入 if 子句。她在那里看到 bar = "123"。如果被调用,这会将值 “123” 分配给未初始化的局部变量 bar

bar= 不能是实例方法(例如,@bar 的 setter),因为任何名称以等号结尾的方法都必须在 显式接收者。 (它的工作方式允许编码人员使用与实例变量同名的局部变量,减去前导 @。)

什么是“显式”接收器?如果 Foo 有一个公共(public)实例方法 buz,你可以这样写:

foo = Foo.new
foo.buz

foo 是方法 buz 的显式接收器。要从 Foo 的实例方法之一中调用 buz,您可以使用显式接收器:

self.buz

或者直接写:

buz

在这种情况下,self隐式 接收者。

因为 bar= 只能用一个显式的接收者来写,我们会写:

attr_writer :bar
...
self.bar = "123"

调用@bar的setter。

我们在哪里?啊,我们刚刚得出结论:

if false
bar = "123"
end

如果执行了 if 子句,将给局部变量 bar 赋值,无论是否存在方法 Foo#bar=.

因为 falsefalseif 子句的内容不会被执行,所以 bar 的值 未从 nil 更改。

重要的是局部变量 bar 和实例变量 @bar 就像 night@天。我们可以很容易地证明如下:

a  = 'cat'
@a = 'dog'
a #=> "cat"
a = 'pig'
@a #=> "dog"

关于ruby - 未执行的代码覆盖局部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32161952/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com