Ruby:@@ vs @在类之外的变量?

时间:2016-08-11 16:20:19

标签: ruby

据我所知,在类外部用@声明的变量将成为对象main的实例变量。

从功能上讲,这与宣布为@@?

有何不同

我期待在file2.rb中声明的@test在file1.rb(通过require)中访问时抛出异常,但它没有。这是否意味着始终只有一个主要对象,并且@和@@在此范围内是等效的?

2 个答案:

答案 0 :(得分:0)

不,他们当然不等同:

@foo = 'bar'
instance_variables
# => [:@prompt, :@foo]

@@bar = 'baz'
# warning: class variable access from toplevel
instance_variables
# => [:@prompt, :@foo]

当您require文件时,它会假定require行的上下文。即:

# file1.rb
@foo = 'bar'

# file2.rb
puts instance_variables

# irb
require './file1'
require './file2'
# => [:@prompt, :@foo]

main只是Object的一个实例。您可以阅读more about main here

答案 1 :(得分:0)

  

据我所知,在类外部用@声明的变量将成为对象main的实例变量。

     

从功能上讲,这与宣布为@@?

有何不同

是的,确实如此。 @是一个实例变量,@@是一个类变量。在顶层,@是主对象的实例变量,@@Object的类变量:

@@foo = :bar
# warning: class variable access from toplevel

Object.class_variables
# => [:@@foo]
  

我希望@test中声明的file2.rbfile1.rb(通过require)中访问时会抛出异常,但事实并非如此。

这实际上与您的问题无关:实例变量从不 raiseException访问时,即使它们不存在。在这种情况下,他们只是评估为nil

  

这是否意味着始终只有一个主要对象

是的,有一个主要对象。

  

并且@@@在此范围内是等效的吗?

不,他们不是。顶层的@main的实例变量,顶层的@@Object的类变量。并且由于类变量是由所有子类继承的,并且该类的所有实例及其所有子类和(几乎)所有类都是Object的子类,并且(几乎)所有对象都是Object的(间接)实例,这意味着顶级@@是一个(几乎)全局变量。

因此,顶级@@@的范围非常不同!