问题描述
在符号(@@
)前面加双的Ruby变量是什么?我对以at符号开头的变量的理解是,它是一个实例变量,如PHP中这样:
What are Ruby variables preceded with double at signs (@@
)? My understanding of a variable preceded with an at sign is that it is an instance variable, like this in PHP:
PHP版本
class Person {
public $name;
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
相当于Ruby
class Person
def set_name(name)
@name = name
end
def get_name()
@name
end
end
在符号@@
处的双精度是什么意思,它与在符号上的单精度有何区别?
What does the double at sign @@
mean, and how does it differ from a single at sign?
推荐答案
以@
为前缀的变量是实例变量,而以@@
为前缀的变量是 class变量.查看以下示例;其输出在puts
行末尾的注释中:
A variable prefixed with @
is an instance variable, while one prefixed with @@
is a class variable. Check out the following example; its output is in the comments at the end of the puts
lines:
class Test
@@shared = 1
def value
@@shared
end
def value=(value)
@@shared = value
end
end
class AnotherTest < Test; end
t = Test.new
puts "t.value is #{t.value}" # 1
t.value = 2
puts "t.value is #{t.value}" # 2
x = Test.new
puts "x.value is #{x.value}" # 2
a = AnotherTest.new
puts "a.value is #{a.value}" # 2
a.value = 3
puts "a.value is #{a.value}" # 3
puts "t.value is #{t.value}" # 3
puts "x.value is #{x.value}" # 3
您可以看到@@shared
在类之间共享;在一个实例中设置该值会更改该类甚至子类的所有其他实例的值,在这种情况下,名为@shared
且带有一个@
的变量将不会.
You can see that @@shared
is shared between the classes; setting the value in an instance of one changes the value for all other instances of that class and even child classes, where a variable named @shared
, with one @
, would not be.
[更新]
正如Phrogz在评论中提到的那样,这是Ruby中常见的习惯用法,即使用类本身的实例变量 来跟踪类级别的数据.这可能是一个棘手的问题,需要四处寻找,并且有很多,但可以将其视为修改Class
类,但仅修改 您正在使用的Class
类的实例.一个例子:
As Phrogz mentions in the comments, it's a common idiom in Ruby to track class-level data with an instance variable on the class itself. This can be a tricky subject to wrap your mind around, and there is plenty of additional reading on the subject, but think about it as modifying the Class
class, but only the instance of the Class
class you're working with. An example:
class Polygon
class << self
attr_accessor :sides
end
end
class Triangle < Polygon
@sides = 3
end
class Rectangle < Polygon
@sides = 4
end
class Square < Rectangle
end
class Hexagon < Polygon
@sides = 6
end
puts "Triangle.sides: #{Triangle.sides.inspect}" # 3
puts "Rectangle.sides: #{Rectangle.sides.inspect}" # 4
puts "Square.sides: #{Square.sides.inspect}" # nil
puts "Hexagon.sides: #{Hexagon.sides.inspect}" # 6
我包括了Square
示例(输出nil
),以证明这可能不会达到您期望的100%; 上面链接的文章还有很多其他内容有关该主题的信息.
I included the Square
example (which outputs nil
) to demonstrate that this may not behave 100% as you expect; the article I linked above has plenty of additional information on the subject.
还请记住,与大多数数据一样,在多线程环境,根据dmarkow的评论.
Also keep in mind that, as with most data, you should be extremely careful with class variables in a multithreaded environment, as per dmarkow's comment.
这篇关于@@ variable在Ruby中是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!