我有鲁比文件叫测试 rb
ff="ff"
def test
puts ff
end
我执行它,有错误:
test.rb: 3: in` test: 未定义本地变量或方法'ff for main: object (名称错误)
原因是什么?有文件可以解释吗?
我有鲁比文件叫测试 rb
ff="ff"
def test
puts ff
end
我执行它,有错误:
test.rb: 3: in` test: 未定义本地变量或方法'ff for main: object (名称错误)
原因是什么?有文件可以解释吗?
在 test
方法定义中, test
方法定义中无法进入 test
方法的原因很简单,就是方法(以 def
关键词创建的)创造了新的范围。与分别使用 class
和 module
和 关键词定义类别和模块相同。
main
(顶层物体)的作用与这种情况的范围问题几乎完全无关。
请注意,如果您想要您的 test
方法能够访问定义上下文定义的本地人,请使用 define_method
(或者在您的情况下使用 define_singleton_method
方法),请在此查阅:
ff = "hi"
define_singleton_method("test") { ff }
test #=> "hi"
与 def
关键词不同的是, define_method
方法组不创建新范围,而是关闭当前范围,捕捉任何本地变量。
使用 的理由不是
main
在某种程度上是一个“特例”,而是顶层定义的ivar 是 main
的一等, 因而可以进入 main
上引用的方法。
然而, test
方法与 main
有何关系?这不是一种方法 on just on
main
本身----实际上是一种在 Object
类中定义的私人实例方法。这意味着 test
方法(作为一种私人方法)将几乎可用到您的红宝石方案中的每一个对象。在顶层定义的所有方法( main
)实际上都定义为 Object
类中的私人实例方法。
有关Ruby最高层的更多信息,见此文章:http://banisterfiend.wordpress.com/2010/11/23/what-is-the-ruby-top-level/
Ruby的范围既简单又复杂。
首先,你必须记住,一切都是物体,一切都有一个范围。
要直接回答您的问题, main
是一个对象, 当您写入 def x...
时, 您会重新定义对象上的方法 main
年/年观察温度:
# note the error describes
[1] pry(main)> main main:Object
NameError: undefined local variable or method main for main:Object
from (pry):1:in <main>
# self is the current object, which is main
[2] pry(main)> self
=> main
# note main is an object of type Object
[3] pry(main)> self.class
=> Object
# main has methods
[4] pry(main)> self.methods
=> [:to_s, :public, etc etc]
所以当你写作时
ff = "ff"
def test
puts ff
end
你真正真正要做的是
class main
ff = "ff"
def test
puts ff
end
end
无效, 因为 ff
已经超出范围。 要解决这个问题, 您必须将 < code> ff code > 转换为实例变量, 所以将其名称以 < code @ /code > 预设 。 以下将有效 :
@ff = "ff"
def test
puts @ff
end
test
请注意,对于main
来说,这似乎比普通类(见下文)要特殊。
如果我们有自己的测试课:
class Test1
ff = "ff"
def test
puts ff
end
end
Test1.new.test # undefined variable/method ff error
这失败的原因是 ff
没有按照预期的正确范围定义。 而是覆盖到采集器执行我们分类声明的时间 。
让我们试一下上面的修补方法:
class Test1Fixed
@ff = "ff"
def test
puts @ff
end
end
Test1Fixed.new.test # results in blank line
这很奇怪。
让我们添加此方法 :
def ff?
puts "ff is: #{@ff.nil? ? "nil" : "not nill"}"
end
Test1Fixed.new.ff? # => ff is: nil
为什么是@ff零?
以下可以更明确地说明这一点:
class Test2
puts "Where am i?"
@instance = "instance"
def initialize
puts "Initalize"
end
puts "pants on"
def test
puts "This will NOT output instance : #{@instance}"
end
def self.class_test
puts "This WILL output instance : #{@instance}"
end
end
puts "Creating new Test2 Object"
t = Test2.new
puts "Calling test on Test2 Object"
t.test
puts "Calling class_test on Test2 Class object"
Test2.class_test
运行中我们得到以下输出 :
$ ruby scope.rb
Where am i?
pants on
Creating new Test2 Object
Initalize
Calling test on Test2 Object
This will NOT output instance :
Calling class_test on Test2 Class object
This WILL output instance : instance
如您所见, 内插器按顺序运行于我们的类声明, 就像其它任何地方一样, 并输出我们的 < code> puts code> 语句。 当我们开始调用方法时, 这会更有趣 。 写入 < code\\ intance =... < / code > 和写入 < code > self. instance =... < / code > 相同, 所以您能猜出我们定义的实例在哪里吗? 是的, 在 测试2 类对象上( 不是测试2 对象 ) 。
这就是为什么当我们调用 test
> 时,没有输出任何内容,因为在 test
, self
中, 指向无线
test2
对象,而不是 test2 类对象
(这是我们设置@ intance to be anything! > 。 这就是为什么你在 初始化
中设置实例变量, 在那里, self
指向实际对象。
当我们通过 self. class_ test
来定义类方法,然后在测试2 类对象( Test2. class_ test
)上调用该方法时,你可以看到我们得到预期输出, 因为在此范围内定义了
希望这能说得通
< a href=> "http://rubykoans.com/" rel="noreferrer" > http://rubykoans.com/ 范围部分可能有助于巩固其中一些知识。
在 Ruby 中, 没有 sigil 的名称总是有“ 本地” 范围 。 Ruby 使用词汇范围, 所以在方法中, 名称总是只指该方法 。
The other scopes are global, instance and class. Here is a good document about them: http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Operators#Scope
解决你的问题有几种方法; 我最喜欢的就是通过打印的东西作为论据:
ff = "ff"
def test(ff)
puts ff
end
更有可能的是,您会包装您在课堂上做的事情, 并使用实例变量 。
你也可以只使用一个全球变量($ff),但这样疯狂的谎言。
为什么我不能在Ruby的方法中 访问本地变量?
因为它是一个 < em> 本地变量 < / em > 。 本地变量在它们定义的范围内是本地的。 这就是为什么它们被称作“ 本地变量 ” 。
在此情况下, 您定义了脚本范围中的一个本地变量, 因此它在脚本范围中可见, 并且 nowhere else em> 。
The project I m doing is written in Java and parsers source code files. (Java src up to now). Now I d like to enable parsing Ruby code as well. Therefore I am looking for a parser in Java that parses ...
collection_select and select Rails helpers: Which one should I use? I can t see a difference in both ways. Both helpers take a collection and generates options tags inside a select tag. Is there a ...
All of the following API do the same thing: open a file and call a block for each line. Is there any preference we should use one than another? File.open("file").each_line {|line| puts line} open("...
I ve installed RubyCAS-Client version 2.1.0 as a plugin within a rails app. It s working, but I d like to remove the ?ticket= in the url. Is this possible?
Here s the string: 04046955104021109 I need it to be formatted like so: 040469551-0402-1109 What s the shortest/most efficient way to do that with ruby?
I m building an xml document from a hash. The xml attributes need to be in order. How can this be accomplished? hash.to_xml
Can sources for discrete ruby extension modules live in the same directory, controlled by the same extconf.rb script? Background: I ve a project with two extension modules, foo.so and bar.so which ...
guys which text editor is good for Rubyonrails? i m using Windows and i was using E-Texteditor but its not free n its expired now can anyone plese tell me any free texteditor? n which one is best an ...