Сбор объектов, которые не обязательно назначены никаким переменным / константам
Объекты, которые не присвоены какой-либо переменной / константе, немедленно исчезают (при нормальных обстоятельствах). В следующем, строка "foo"
не захвачен ObjectSpace.each_object(String)
в третьей строке:
strings = ObjectSpace.each_object(String).to_a
"foo"
ObjectSpace.each_object(String).to_a - strings # => []
Можно ли захватывать объекты, которые не обязательно назначены каким-либо переменным / константам или частью каких-либо переменных / констант? Я особенно заинтересован в захвате строк. Соответствующий домен может быть файлом или блоком. Я ожидаю что-то вроде следующего:
capture_all_strings do
...
"a"
s = "b"
@s = "c"
@@s = "d"
S = "e"
%q{f}
...
end
# => ["a", "b", "c", "d", "e", "f"]
1 ответ
Ruby создает строковые экземпляры при разборе вашего файла. Вот пример: строка
"aaa #{123} zzz"
анализируется как:
$ ruby --dump=parsetree -e '"aaa #{123} zzz"'
###########################################################
## Do NOT use this node dump for any purpose other than ##
## debug and research. Compatibility is not guaranteed. ##
###########################################################
# @ NODE_SCOPE (line: 1)
# +- nd_tbl: (empty)
# +- nd_args:
# | (null node)
# +- nd_body:
# @ NODE_DSTR (line: 1)
# +- nd_lit: "aaa "
# +- nd_next->nd_head:
# | @ NODE_EVSTR (line: 1)
# | +- nd_body:
# | @ NODE_LIT (line: 1)
# | +- nd_lit: 123
# +- nd_next->nd_next:
# @ NODE_ARRAY (line: 1)
# +- nd_alen: 1
# +- nd_head:
# | @ NODE_STR (line: 1)
# | +- nd_lit: " zzz"
# +- nd_next:
# (null node)
На этапе синтаксического анализа есть два строковых литерала, "aaa "
а также " zzz"
:
# +- nd_lit: "aaa "
# ...
# | +- nd_lit: " zzz"
инспектирование ObjectSpace
подтверждает, что эти строки были созданы:
$ ruby -e '"aaa #{123} zzz"; ObjectSpace.each_object(String) { |s| p s }' | egrep "aaa|zzz"
"\"aaa \#{123} zzz\"; ObjectSpace.each_object(String) { |s| p s }\n"
"aaa 123 zzz"
" zzz"
"aaa "
Поэтому, если вы не создаете новый экземпляр строки (например, присваивая строковый литерал переменной), вы не можете обнаружить создание строки. Это уже там, когда код выполняется.