Trong MRI, có vẻ như rb_id2str()
có trách nhiệm thực hiện tất cả công việc khi bạn gọi Symbol#to_s
. Tôi đã rất ngạc nhiên khi phát hiện ra đây là một hàm cực kỳ khó hiểu đối với một cái gì đó mà tôi cho là một hoạt động khá thẳng về phía trước.MRI Internals: giải thích chi tiết về rb_id2str
Tôi đang tìm kiếm giải thích chi tiết về chức năng này đang làm. Để tham khảo, đây là một liên kết đến các nguồn trong 1.9.3:
http://rxr.whitequark.org/mri/source/parse.y?v=1.9.3-p195#9950
Một số câu hỏi cụ thể:
bốn lớn if
khối đang làm gì?
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))
Nó sẽ là tuyệt vời để có được một cái nhìn tổng quan chung về những gì mỗi khối mã bên trong nếu báo cáo không, nhưng nó doesn' t cần phải là một phân tích theo từng dòng.
Cuối cùng, tôi tò mò về ý nghĩa thu thập rác/bộ nhớ của to_s
: gọi Symbol#to_s
tạo chuỗi mới phải thu gom rác mỗi lần hoặc có thứ gì đó như tối ưu hóa sao chép nội bộ sử dụng một tham chiếu đến biểu diễn bên trong của biểu tượng cho đến khi một đột biến được tạo thành chuỗi?
'rb_id2str' làm được nhiều hơn thế. 'Biểu tượng # to_s' thực sự tương đương với' rb_sym_to_s'. Hàm đó lấy ID của đối tượng bằng cách sử dụng 'SYM2ID' và chỉ sau đó nó gọi' rb_id2str' với ID được trả về bởi 'SYM2ID' làm tham số để xây dựng một chuỗi từ ID của đối tượng. Có thể có một số bước mà tôi bỏ qua, mặc dù. Tôi chắc chắn về việc sử dụng bộ nhớ liên quan đến 'to_s', nhưng tôi đoán (và hy vọng) nó không tạo ra một chuỗi mới – omninonsense