由于我的编码有些草率,我注意到未声明的实例变量的求值结果似乎为零,而未声明的局部变量则没有。这个实例变量的默认nill值是我可以利用的行为(比如用一个条件来检查变量是否设置为true(,还是这只是一个应该独处的怪癖?
2.6.6 :001 > puts @test
=> nil
2.6.6 :002 > puts test
Traceback (most recent call last):
2: from (irb):2
1: from (irb):2:in `test'
ArgumentError (wrong number of arguments (given 0, expected 2..3))
根据Ruby文档:
ruby的实例变量不需要声明。这意味着一个灵活的对象结构。事实上,每个实例变量在第一次被引用时都会动态地附加到对象上。
https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/instancevars.html
您还可以获得所有先前定义的实例变量的列表:
ClassName.instance_variables
或
a = ClassName.new
a.instance_variables #specific to instance
tl;dr 是的,这在Assignment中有记录。
一个事物是否被定义,以及它被定义为什么,可以用defined?
关键字来表示。
2.6.5 :003 > defined?(fnord)
=> nil
2.6.5 :004 > fnord = 42
=> 42
2.6.5 :005 > defined?(fnord)
=> "local-variable"
2.6.5 :006 > defined?($fnord)
=> nil
2.6.5 :007 > $fnord = 42
=> 42
2.6.5 :008 > defined?($fnord)
=> "global-variable"
2.6.5 :009 > defined?(@fnord)
=> nil
2.6.5 :010 > @fnord = 42
=> 42
2.6.5 :011 > defined?(@fnord)
=> "instance-variable"
2.6.5 :012 > defined?(FNORD)
=> nil
2.6.5 :013 > FNORD = 42
=> 42
2.6.5 :014 > defined?(FNORD)
=> "constant"
这对调试很有用,但我不鼓励";利用";它在应用程序代码中。
首先,让我们来清理一下您的示例。CCD_ 2是CCD_ 3的一种方法。它继承自Kernel#测试。
2.6.5 :004 > defined?(test)
=> "method"
2.6.5 :005 > method(:test)
=> #<Method: main.test>
一个恰当的例子是这样的。
2.6.5 :008 > puts @fnord
=> nil
2.6.5 :009 > puts fnord
Traceback (most recent call last):
4: from /Users/schwern/.rvm/rubies/ruby-2.6.5/bin/irb:23:in `<main>'
3: from /Users/schwern/.rvm/rubies/ruby-2.6.5/bin/irb:23:in `load'
2: from /Users/schwern/.rvm/rubies/ruby-2.6.5/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
1: from (irb):9
NameError (undefined local variable or method `fnord' for main:Object)
局部变量
这个错误暗示了正在发生的事情:歧义。CCD_ 4可以是局部变量CCD_ 5或CCD_。两者都没有声明,Ruby不会猜到你的意思,所以你会得到一个NameError。
在Ruby中,局部变量名和方法名几乎相同。如果您还没有分配给这些不明确的名称中的一个,ruby将假设您希望调用一个方法。一旦您指定了名称ruby,就会假设您希望引用一个局部变量。
可以使用local_variables发现声明的局部变量。
2.6.5 :012 > foo = 42
=> 42
2.6.5 :013 > Kernel.local_variables
=> [:foo, :_]
实例变量
未初始化的实例变量的值为nil如果在启用警告的情况下运行Ruby,则在访问未初始化的实例变量时会收到警告。
有各种方法可以内省实例变量,如instance_variables
和instance_variables_defined?
。虽然在某些情况下,在编写库时这可能是必要的,但我强烈反对利用nil
和";未定义的";在应用程序代码中;它使事物变得脆弱。
类变量
访问未初始化的类变量将引发NameError异常。
全局变量
未初始化的全局变量的值为nil。