我是ruby的新手,也是编程的新手。我在一个独立的ruby脚本中有一段代码,它从yaml文件中读取数据并将该数据分配给方法中的变量。这都是在一种方法中完成的。 在方法定义之外,我调用该方法并打印分配的变量的值。但是,呃哦,方法中赋值的变量的值是零...为什么?这与我假设的面向对象编程有关。有人可以详细说明吗?
以下是代码。提前谢谢。
#!/usr/bin/env ruby
require 'pg'
require 'yaml'
source_connection=nil
def load_configurations
file_name = nil
ARGV.each do|a|
file_name = "#{a}"
end
dest_options = YAML.load_file(file_name)
source_connection = dest_options['dest_name']
end
load_configurations()
puts source_connection
##### returns nothing. why? #####
答案 0 :(得分:5)
在Ruby中,就像在大多数语言中一样(至少我知道,Javascript可能是一个例外),有一个名为可见范围的概念。
Ruby中有四个范围:
在实践中,它意味着为ex定义的局部变量。 in方法仅在此方法中可见,除非您显式向上传入(使用方法/块调用参数)或向下传入(使用返回)调用堆栈。
在你的情况下,在你将source_connection
分配给nil的方法之外会发生什么,但是你在不同的范围内引用相同的var名称,因此只在那里分配。解决这个问题的Ruby方法是定义实例变量(@source_connection
)或将此变量显式传递到方法中然后返回它。
专业提示:在Ruby中,默认情况下会返回最后一次评估,因此您无需显式写入return source_connection
。
编辑:
对于类实例和实例变量,事情变得有点复杂,所以如果我只是指向Metaprogramming Ruby书的方向,那么最好的就是完美地列出这些主题。
EDIT2:
我的重写建议(有一点风格改变 - 对于方法定义,无论有没有params,总是添加parentheres是好的。另一方面,如果没有或只有一个参数,你可以省略,但这取决于个人味道 ;)
我还将缩进改为2个空格 - 我认为它是最常用的。
#!/usr/bin/env ruby
require 'pg'
require 'yaml'
def load_configurations()
file_name = nil
ARGV.each do|a|
file_name = "#{a}"
end
dest_options = YAML.load_file(file_name)
dest_options['dest_name'] # Ruby will return last evaluation
end
source_connection = load_configurations
puts source_connection # now it will print what you expect
答案 1 :(得分:3)
变量在方法范围内创建,不会设置为全局范围中定义的变量。有关更多信息,这可能是一个很好的阅读:http://www.techotopia.com/index.php/Ruby_Variable_Scope
你应该可以这样做:
def load_configurations
file_name = nil
ARGV.each do |a|
file_name = "#{a}"
end
dest_options = YAML.load_file(file_name)
dest_options['dest_name']
end
source_connection = load_configurations
puts source_connection