Skip to content

Instantly share code, notes, and snippets.

@pjambet
Last active August 10, 2020 20:30
Show Gist options
  • Save pjambet/01b54af23790b9a279c45ae07c7ec4a5 to your computer and use it in GitHub Desktop.
Save pjambet/01b54af23790b9a279c45ae07c7ec4a5 to your computer and use it in GitHub Desktop.
A ruby Array, from Scratch, only for Strings
require 'fiddle'
class BYOArray < BasicObject
PTR_SIZE = ::Fiddle::SIZEOF_LONG
def initialize(max_size)
@max_size = max_size
@current_size = 0
@beginning_address = ::Fiddle::Pointer.malloc(PTR_SIZE)
end
def add(str)
::Kernel.raise 'Array is full' if @current_size == @max_size
ptr = ::Fiddle::Pointer.to_ptr(::Marshal.dump(str))
offset = @current_size * PTR_SIZE # 0 at first, then 8, 16, etc ...
@beginning_address[offset, PTR_SIZE] = ptr.ref
@current_size += 1
self
end
def get(i)
return nil if i < 0 || i >= @current_size
address = @beginning_address[i * PTR_SIZE, PTR_SIZE].unpack('Q')[0]
::Marshal.load(::Fiddle::Pointer.new(address).to_s)
end
def to_s
"Size: #{ @current_size }"
end
end
C = ::Struct.new(:a)
ary = BYOArray.new(10)
::Kernel.puts ary.add("foo")
::Kernel.puts ary.add(C.new(1))
::Kernel.puts ary.get(0)
::Kernel.puts ary.get(1)
::Kernel.puts ary.get(2)
::Kernel.puts ary.add("bar")
require 'fiddle'
class BYOArray < BasicObject
PTR_SIZE = ::Fiddle::SIZEOF_LONG
def initialize(max_size)
@max_size = max_size
@current_size = 0
@beginning_address = ::Fiddle::Pointer.malloc(PTR_SIZE)
end
def add(str)
::Kernel.raise 'Array is full' if @current_size == @max_size
::Kernel.raise 'Expected a string' unless str.is_a?(::String)
ptr = ::Fiddle::Pointer.to_ptr(str)
offset = @current_size * PTR_SIZE # 0 at first, then 8, 16, etc ...
@beginning_address[offset, PTR_SIZE] = ptr.ref
@current_size += 1
self
end
def get(i)
return nil if i < 0 || i >= @current_size
address = @beginning_address[i * PTR_SIZE, PTR_SIZE].unpack('Q')[0]
::Fiddle::Pointer.new(address).to_s
end
def to_s
"Size: #{ @current_size }"
end
end
ary = BYOArray.new(2)
::Kernel.puts ary.add("foo")
::Kernel.puts ary.add("bar")
::Kernel.puts ary.get(0)
::Kernel.puts ary.get(1)
::Kernel.puts ary.get(2)
::Kernel.puts ary.add("bar")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment