rubypointersmri

Ruby How we can unfreeze the string using pointer


I was going through a blog and found following code snippet:

require 'fiddle'
str = 'water'.freeze
str.frozen? # true

memory_address = str.object_id * 2
Fiddle::Pointer.new(memory_address)[1] &= ~8
str.frozen? # false

Can anyone explain, I couldn't understand how following line is actually unfreeze the string.

Fiddle::Pointer.new(memory_address)[1] &= ~8

Solution

  • MRI heap stores RValue struct at that address, first field of that is flags, which has bit FL_FREEZE indicating if the object is frozen - 11th bit in an integer, in x86 bytes go in reverse order, so it can be accessed as 3rd bit of second byte.

    The code sets that bit to zero thus 'unfreezing' the object