W MRI wygląda na to, że rb_id2str()
jest odpowiedzialny za wykonanie całej pracy po wywołaniu Symbol#to_s
. Byłem zaskoczony, gdy odkryłem, że jest to niezwykle tajemnicza funkcja dla czegoś, co według mnie byłoby dość prostą operacją.MRI Internals: szczegółowe wyjaśnienie rb_id2str
Szukam szczegółowego wyjaśnienia, co robi ta funkcja. Dla porównania, tutaj jest link do źródła w 1.9.3:
http://rxr.whitequark.org/mri/source/parse.y?v=1.9.3-p195#9950
Niektóre konkretne pytania:
Jakie są cztery główne bloki if
robi?
if (id < tLAST_TOKEN)
if (id < INT_MAX && rb_ispunct((int)id))
if (st_lookup(global_symbols.id_str, id, &data))
if (is_attrset_id(id))
Byłoby wspaniale, aby uzyskać ogólny przegląd tego, co każdy blok kodu wewnątrz if robi, ale nie robi” t musi być analizą liniową.
Wreszcie, ciekawi mnie konsekwencje związane z pamięcią/usuwaniem śmieci: to_s
: czy wywołanie Symbol#to_s
tworzy nowy ciąg, który musi być zawsze usuwany ze śmiecia, czy też jest coś takiego jak wewnętrzna optymalizacja kopiowania przy zapisie, która wykorzystuje odniesienie do internowanej reprezentacji symbolu aż do wprowadzenia mutacji w ciągu znaków?
'rb_id2str' robi o wiele więcej niż tylko to. 'Symbol # to_s' jest faktycznie równoważny' rb_sym_to_s'. Ta funkcja pobiera identyfikator obiektu za pomocą 'SYM2ID' i tylko wtedy wywołuje' rb_id2str' z identyfikatorem zwróconym przez 'SYM2ID' jako parametr do skonstruowania łańcucha z identyfikatora obiektu. Jednak mogą być pewne kroki, które przeoczyłem. Jestem pewien co do użycia pamięci związanej z 'to_s', ale zgaduję (i mam nadzieję), że nie tworzy on nowego ciągu – omninonsense