调用方法和方法调用变量时的局部变量

时间:2016-01-25 05:19:04

标签: ruby

在以下代码中,atimes之外初始化,但times创建了内部范围,a可供访问:

a = 5
3.times do |n|
  a = 3
end
a # => 3

a的返回值为3,因为a可以从3.times do ... end创建的范围中获得a,因此可以重新分配a的值。事实上,它已将3重新分配给a = 5 def adder(num) num = 3 end adder(a) # => 3 a # => 5 三次。

为什么以下与上述不同?

a

这是因为我们引入了a,但它并没有改变局部变量,可能是因为它是一个方法。我不知道。为什么5 3而非myfield = "Sno"; value ={{:myfield}}

3 个答案:

答案 0 :(得分:2)

所有没有字形(@@@$)的Ruby变量都是当前方法,模块,类或当前程序的本地变量。

a = 5  # local to program

def adder
  # local to method
  num = 3
  puts num
end
adder(1)
# => 3

module Foo
  # local to module
  num = 2
  puts num
end
# => 2

class Bar
  # local to class
  num = 1
  puts num
end
# => 1

a      # local to program
# => 5

在这些变量中,变量的范围限定在引入它们的块中,正如您自己记下的那样。

答案 1 :(得分:1)

你的两个例子不一样。第一个是带有块的方法调用。块是闭包,这意味着它们会记住定义它们的上下文(特别是保留对该范围中变量的引用)。

第二个是方法定义。这不是封闭。事实上,它是一个所谓的范围门"。这意味着当方法(/ class / module)的定义开始时,所有先前已知的局部变量都被推出范围。因此,如果您要从a内访问adder,则会获得NameError

而且,正如@Atri所说,你的方法定义没有机会像你期望的那样工作。你甚至不会在那里分配a。那么您如何期望a改变?

答案 2 :(得分:0)

  

为什么a 5而不是3?

a = 5
def adder(num)
  num = 3
end
adder(a) # => 3
a # => 5

因为当您使用adder致电a时,它是pass by value。因此,当num的值发生更改时,它不会更改a的值。

如果您希望a更改值,则需要执行a = adder(a)