何时可以访问局部变量?

时间:2019-03-09 19:31:08

标签: ruby

这是来自ruby-doc第4.3节中给出的示例,该链接位于以下链接中:

Ruby-Doc

解释如下:

  

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。如果我错了,请纠正我。

3 个答案:

答案 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

除非您一开始做傻事,否则碰到这种情况并不常见。