一本书说我们在ruby中声明/初始化/定义的所有标识符和变量都将作为符号包含在内部符号表中;然后Ruby会在程序中的任何位置使用包含的符号时查找它。例如,在过程中:
a = "1"
a
:a
。 a
:
def a
puts "stack_overflow"
end
变量a
和标识符def a
中存储了单个符号:a
。我使用Symbol.all_symbols.count
检查了符号计数。伯爵是一样的;即,添加def a
并未增加符号表计数。
当ruby在代码中的任何位置看到a
时,如何区分变量def a
和标识符a
?
在s = :x
中,符号变量s
是存储在符号表中的,还是只存储在:x
?
答案 0 :(得分:4)
计数是一样的;即,添加
def a
并未增加符号表计数。
这是因为符号:a
已经存在:
$ ruby -e "puts Symbol.all_symbols.count"
2504
$ ruby -e "puts Symbol.all_symbols" | grep ^a | sort | head -n 5
a
abort
abort_on_exception
abort_on_exception=
abs
您可以使用--disable-gems
选项启动Ruby以摆脱它(以及许多其他符号):
$ ruby --disable-gems -e "puts Symbol.all_symbols.count"
1689
$ ruby --disable-gems -e "puts Symbol.all_symbols" | grep ^a | sort | head -n 5
abort
abort_on_exception
abort_on_exception=
abs
abs2
现在,定义或引用a
实际上会增加符号数:
$ ruby --disable-gems -e "puts Symbol.all_symbols.count"
1689
$ ruby --disable-gems -e "def a; end; puts Symbol.all_symbols.count"
1690
$ ruby --disable-gems -e "a = 1; puts Symbol.all_symbols.count"
1690
答案 1 :(得分:1)
内部的符号实际上是一个常量字符串到一个整数的映射,并且在查找之后它们的行为方式如下所示 - 符号上的索引比字符串上的索引更快(如果哈希有符号键),也是符号变量消耗与Fixnums一样多的内存
关于查询 - 红宝石的环境'对于每个具有局部变量表的执行上下文,它们都是嵌套的,因此名称可以重载。 全球范围也有背景。
所以看到一个名字(此时名字已经是一个符号) - ruby在当前上下文中查找具有此名称的变量,然后查找方法,然后再在父上下文等中查找(简化后,还检查了其他几项内容) )