ruby 中符号的解析方式
How symbols are resolved in ruby
一本书上说我们declare/initialize/define在ruby中的所有标识符和变量都会作为符号包含在内部符号table中;然后 Ruby 在程序中的任何地方使用包含的符号时查找它。例如,在程序中:
a = "1"
- Ruby 在其 table.
中包含变量 a
作为 :a
a
在程序中使用:
def a
puts "stack_overflow"
end
变量 a
和标识符 def a
中存储了单个符号 :a
。我使用 Symbol.all_symbols.count
检查了符号数。计数是一样的;即,添加 def a
不会增加符号 table 计数。
当 ruby 在代码的任何地方看到 a
时,它如何区分变量 a
和标识符 def a
?
在s = :x
中,是符号变量s
存储在符号table中,还是只是:x
?
符号深处实际上是常量字符串到整数的映射,查找后它们的行为方式是这样的,例如 - 对符号的索引比对字符串的索引更快(如果散列具有符号键),也符号变量消耗的内存与 Fixnums
一样多
关于查找 - ruby 对每个执行上下文都有 'environment',其中有局部变量 table,它们是嵌套的,因此名称可以重载。
全局范围也有上下文。
所以在看到一个名称时(此时名称已经是一个符号)- ruby 在当前上下文中查找具有此名称的变量,然后查找方法,然后在父上下文中再次查找等(简化,还有其他几项检查)
The count was the same; i.e., adding def a
did not increase the symbol table count.
这是因为符号: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
一本书上说我们declare/initialize/define在ruby中的所有标识符和变量都会作为符号包含在内部符号table中;然后 Ruby 在程序中的任何地方使用包含的符号时查找它。例如,在程序中:
a = "1"
- Ruby 在其 table. 中包含变量
a
在程序中使用:def a puts "stack_overflow" end
a
作为 :a
变量 a
和标识符 def a
中存储了单个符号 :a
。我使用 Symbol.all_symbols.count
检查了符号数。计数是一样的;即,添加 def a
不会增加符号 table 计数。
当 ruby 在代码的任何地方看到 a
时,它如何区分变量 a
和标识符 def a
?
在s = :x
中,是符号变量s
存储在符号table中,还是只是:x
?
符号深处实际上是常量字符串到整数的映射,查找后它们的行为方式是这样的,例如 - 对符号的索引比对字符串的索引更快(如果散列具有符号键),也符号变量消耗的内存与 Fixnums
一样多关于查找 - ruby 对每个执行上下文都有 'environment',其中有局部变量 table,它们是嵌套的,因此名称可以重载。 全局范围也有上下文。
所以在看到一个名称时(此时名称已经是一个符号)- ruby 在当前上下文中查找具有此名称的变量,然后查找方法,然后在父上下文中再次查找等(简化,还有其他几项检查)
The count was the same; i.e., adding
def a
did not increase the symbol table count.
这是因为符号: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