如何在ruby中解析符号

时间:2015-12-09 10:40:25

标签: ruby symbols

一本书说我们在ruby中声明/初始化/定义的所有标识符和变量都将作为符号包含在内部符号表中;然后Ruby会在程序中的任何位置使用包含的符号时查找它。例如,在过程中:

  • a = "1"
  • Ruby在其表中包含变量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

2 个答案:

答案 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​​在当前上下文中查找具有此名称的变量,然后查找方法,然后再在父上下文等中查找(简化后,还检查了其他几项内容) )