这是来自ruby-doc第4.3节中给出的示例,该链接位于以下链接中:
解释如下:
Ruby查找赋值语句。如果在源中的某个时刻使用
a'' it sees it being assigned to, it decides to parse
a''作为变量,否则它将其视为方法。
示例如下
def a
print "Function 'a' called\n"
99
end
for i in 1..2
if i == 2
print "a=", a, "\n"
else
a = 1
print "a=", a, "\n"
end
end
输出为
a=1
Function 'a' called
a=99
但是从代码中可以明显看出,当i为1时,将a分配给1,然后将1打印为a的值。然后对于i = 2,将调用方法“ a”。
现在,如果我在for循环外打印“ a”会怎样?我得到的值是1,但我不知道怎么可能。如果将方法的先前值从a重新分配为1将会在各处进行更改,那么在i = 2期间,输出也应该为1。如果我错了,请纠正我。
答案 0 :(得分:1)
当您分配a = 1
时,您将“覆盖”功能a
。我希望这小段代码可以对您有所帮助:
def a
'function a'
end
p a.class #=> String returned by the function
a = 1
p a.class #=> Integer "overridden" by a=1
p a().class #=> String the function is not lost, needs to be called with round brackets.
答案 1 :(得分:0)
您的示例中没有“本地”。在ruby中,大多数事物都是可以访问的,除非它们在可以被“本地化”的类或模块定义中定义。这是您编写简单类的方法
class Foo
def self.a
'a'
end
end
在这里,我们只是定义一个单一的类方法,该方法将始终返回无法修改的字符串a
。如果要封装,建议不要编写没有封装的东西。否则,您几乎可以在Ruby中的任何地方进行任何修改,这就是为什么它是元编程的好语言的原因。对于其他想法,也许have a look here
答案 2 :(得分:0)
未到达代码分支中的赋值语句确实会影响局部变量。
class Foo
def method_missing(meth, *args)
"returned from method_missing #{meth}"
end
end
Foo.new.instance_exec do
puts abc.inspect # abc is considered a method
if true == false
abc = 1 # <-- this should never be reached
end
puts abc.inspect # abc is considered a local variable
end
这将输出:
"returned from method_missing abc" # <- the return value from method_missing
nil # <- suddenly abc is nil, even though abc wasn't touched.
因此,Ruby看到分配给局部变量abc
的代码,并决定从abc
开始,该变量是变量,而不是方法调用。
我相信这样做是为了在没有NoMethodError
的情况下允许这样的事情:
if something
a = true
end
if a
puts "ah yes, a."
end
除非您一开始做傻事,否则碰到这种情况并不常见。