主键上的Ruby作用域
我想了解此代码不起作用的原因:主键上的Ruby作用域,ruby,Ruby,我想了解此代码不起作用的原因: array = [1,2,3] def display_size() puts "self from method: #{self}" puts "Size from method: #{array.size}" end puts "self from main: #{self}" puts "Size from main: #{array.size}" display_size() 出现错误的输出: $ ruby scope.rb sel
array = [1,2,3]
def display_size()
puts "self from method: #{self}"
puts "Size from method: #{array.size}"
end
puts "self from main: #{self}"
puts "Size from main: #{array.size}"
display_size()
出现错误的输出:
$ ruby scope.rb
self from main: main
Size from main: 3
self from method: main
scope.rb:5:in `display_size': undefined local variable or method `array' for main:Object (NameError)
from scope.rb:10:in `<main>'
$ruby scope.rb
来自main的self:main
主管道尺寸:3
方法:main
scope.rb:5:在“display_size”中:未定义的局部变量或main:Object的“array”方法(NameError)
from scope.rb:10:in`'
我推测这是一个范围问题。我猜这意味着该方法中有一个新的作用域,array
不可见
最初我希望变量与方法在同一范围内,因为它们都是在main上定义的…实际上,这是一个范围问题。如果您想在该方法中访问
array
,请将其更改为@array
@array = [1,2,3]
def display_size()
puts "self from method: #{self}"
puts "Size from method: #{@array.size}"
end
puts "self from main: #{self}"
puts "Size from main: #{@array.size}"
display_size()
array
是一个局部变量,仅在局部范围内起作用
@array
是一个实例变量,在同一类中的任何地方都可用
如果希望避免创建实例变量,则需要将数组传递给方法
array = [1,2,3]
def display_size(array)
puts "self from method: #{self}"
puts "Size from method: #{array.size}"
end
puts "self from main: #{self}"
puts "Size from main: #{array.size}"
display_size(array)
事实上,这是一个范围问题。如果您想在该方法中访问
array
,请将其更改为@array
@array = [1,2,3]
def display_size()
puts "self from method: #{self}"
puts "Size from method: #{@array.size}"
end
puts "self from main: #{self}"
puts "Size from main: #{@array.size}"
display_size()
array
是一个局部变量,仅在局部范围内起作用
@array
是一个实例变量,在同一类中的任何地方都可用
如果希望避免创建实例变量,则需要将数组传递给方法
array = [1,2,3]
def display_size(array)
puts "self from method: #{self}"
puts "Size from method: #{array.size}"
end
puts "self from main: #{self}"
puts "Size from main: #{array.size}"
display_size(array)
假设您的代码是正在执行的方法的主体:
class MyClass
def inspect
'my_main'
end
def to_s
inspect
end
def foo
array = [1,2,3]
def display_size
puts "self from method: #{self}"
puts "Size from method: #{array.size}"
end
puts "self from main: #{self}"
puts "Size from main: #{array.size}"
display_size
end
end
my_main = MyClass.new
my_main.foo
输出几乎相同:
self from main: my_main
Size from main: 3
self from method: my_main
scope.rb:15:in `display_size': undefined local variable or method `array' for my_main:MyClass (NameError)
from scope.rb:20:in `foo'
from scope.rb:25:in `<main>'
我认为很明显,
array
无法从display\u size
中访问。假设您的代码是正在执行的方法的主体:
class MyClass
def inspect
'my_main'
end
def to_s
inspect
end
def foo
array = [1,2,3]
def display_size
puts "self from method: #{self}"
puts "Size from method: #{array.size}"
end
puts "self from main: #{self}"
puts "Size from main: #{array.size}"
display_size
end
end
my_main = MyClass.new
my_main.foo
输出几乎相同:
self from main: my_main
Size from main: 3
self from method: my_main
scope.rb:15:in `display_size': undefined local variable or method `array' for my_main:MyClass (NameError)
from scope.rb:20:in `foo'
from scope.rb:25:in `<main>'
我认为很明显,
array
无法从display\u size
中访问,以小写字母开头的变量是局部变量。它们被称为局部变量,因为它们在定义它们的范围内是局部的
在示例中有两个作用域:代码所在文件的脚本作用域和display\u size
的方法作用域。脚本范围中的局部变量array
和方法范围中的局部变量array
是两个不同的局部变量。(后一个事实上并不存在,这就是你看到错误的原因。)这就是作用域和局部变量的全部意义,你可以在代码的不同部分重复使用局部变量的名称
想象一下,如果不是这样的话,会发生什么情况:那么整个地球上的每个Ruby程序员都必须与地球上的每个其他Ruby程序员就如何命名其局部变量达成一致。如果我的代码中有一个名为address
的局部变量,那么世界上没有其他人可以使用该名称作为局部变量的名称
有几种方法可以解决这个问题
第一种方法是使用嵌套作用域。在Ruby中,只有一个构造创建了嵌套的作用域:块。(嗯,是拉姆达文字,但我会考虑那些是相同的。)< /P>
因此,您可以使用lambda文本而不是方法:
display_size = -> {
puts "self from lambda: #{self}"
puts "Size from lambda: #{array.size}"
}
display_size.()
# self from lambda: main
# Size from lambda: 3
或者,如果要使用方法,则需要使用块创建方法。谢天谢地,有这样一种方法可以从块中创建方法:Module\define\u method
:
define_method(:display_size) do
puts "self from method: #{self}"
puts "Size from method: #{array.size}"
end
display_size
# self from method: main
# Size from method: 3
另一种方法是将数组作为参数传递给方法;参数绑定成为方法体中的局部变量:
def display_size(array)
puts "self from method: #{self}"
puts "Size from method: #{array.size}"
end
display_size(array)
# self from method: main
# Size from method: 3
(请注意,我们现在在两个不同的范围内有两个不同的局部变量array
。)
第三种方法是使用实例变量、类变量、全局变量或常量而不是局部变量:
def display_size
puts "self from method: #{self}"
puts "Size from method: #{@array.size}"
end
@array = [1, 2, 3]
display_size
# self from method: main
# Size from method: 3
def display_size
puts "self from method: #{self}"
puts "Size from method: #{@@array.size}"
end
@@array = [1, 2, 3]
display_size
# self from method: main
# Size from method: 3
def display_size
puts "self from method: #{self}"
puts "Size from method: #{$array.size}"
end
$array = [1, 2, 3]
display_size
# self from method: main
# Size from method: 3
def display_size
puts "self from method: #{self}"
puts "Size from method: #{Ary.size}"
end
Ary = [1, 2, 3]
display_size
# self from method: main
# Size from method: 3
(请注意,在上一个示例中,我是如何使用
Ary
而不是Array
的?同样,这是因为在范围中已经定义了一个名为Array
的常量。)以小写字母开头的变量是局部变量。它们被称为局部变量,因为它们在定义它们的范围内是局部的
在示例中有两个作用域:代码所在文件的脚本作用域和display\u size
的方法作用域。脚本范围中的局部变量array
和方法范围中的局部变量array
是两个不同的局部变量。(后一个事实上并不存在,这就是你看到错误的原因。)这就是作用域和局部变量的全部意义,你可以在代码的不同部分重复使用局部变量的名称
想象一下,如果不是这样的话,会发生什么情况:那么整个地球上的每个Ruby程序员都必须与地球上的每个其他Ruby程序员就如何命名其局部变量达成一致。如果我的代码中有一个名为address
的局部变量,那么世界上没有其他人可以使用该名称作为局部变量的名称
有几种方法可以解决这个问题
第一种方法是使用嵌套作用域。在Ruby中,只有一个构造创建了嵌套的作用域:块。(嗯,是拉姆达文字,但我会考虑那些是相同的。)< /P>
因此,您可以使用lambda文本而不是方法:
display_size = -> {
puts "self from lambda: #{self}"
puts "Size from lambda: #{array.size}"
}
display_size.()
# self from lambda: main
# Size from lambda: 3
或者,如果要使用方法,则需要使用块创建方法。谢天谢地,有这样一种方法可以从块中创建方法:Module\define\u method
:
define_method(:display_size) do
puts "self from method: #{self}"
puts "Size from method: #{array.size}"
end
display_size
# self from method: main
# Size from method: 3
另一种方法是将数组作为参数传递给方法;参数绑定成为方法体中的局部变量:
def display_size(array)
puts "self from method: #{self}"
puts "Size from method: #{array.size}"
end
display_size(array)
# self from method: main
# Size from method: 3
(请注意,我们现在在两个不同的范围内有两个不同的局部变量array
。)
第三种方法是使用实例变量、类变量、全局变量或常量而不是局部变量:
def display_size
puts "self from method: #{self}"
puts "Size from method: #{@array.size}"
end
@array = [1, 2, 3]
display_size
# self from method: main
# Size from method: 3
def display_size
puts "self from method: #{self}"
puts "Size from method: #{@@array.size}"
end
@@array = [1, 2, 3]
display_size
# self from method: main
# Size from method: 3
def display_size
puts "self from method: #{self}"
puts "Size from method: #{$array.size}"
end
$array = [1, 2, 3]
display_size
# self from method: main
# Size from method: 3
def display_size
puts "self from method: #{self}"
puts "Size from method: #{Ary.size}"
end
Ary = [1, 2, 3]
display_size
# self from method: main
# Size from method: 3
(注意我是如何使用A的。)