Created
July 4, 2026 03:37
-
-
Save havenwood/ab39544cd39f79fe7bbc8364022d235c to your computer and use it in GitHub Desktop.
superclass=
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require "fiddle" | |
| require_relative "settable_superclass" | |
| class Klass | |
| using SettableSuperclass | |
| HEAP_TYPE = ->(obj) { Fiddle::Pointer.new(Fiddle.dlwrap(obj))[0, Fiddle::SIZEOF_VOIDP].unpack1("J") & 0x1f } | |
| private_constant :HEAP_TYPE | |
| def initialize(superclass = Object) | |
| class << self | |
| attr_reader :superclass | |
| def superclass=(new_super) | |
| raise FrozenError, "can't modify frozen #{self.class}" if frozen? | |
| if new_super.instance_of?(Class) && HEAP_TYPE.call(new_super.allocate) != HEAP_TYPE.call(self) | |
| raise TypeError, "#{new_super} instances have an incompatible heap layout" | |
| end | |
| singleton_class.superclass = new_super | |
| @superclass = new_super | |
| end | |
| def with_superclass(new_super, &block) | |
| original = superclass | |
| self.superclass = new_super | |
| begin | |
| block.call(self) | |
| ensure | |
| self.superclass = original | |
| end | |
| end | |
| def deconstruct_keys(keys) = {superclass: @superclass} | |
| def <(other) | |
| raise TypeError, "compared with non class/module" unless other.is_a?(Module) | |
| singleton_class.ancestors.include?(other) || nil | |
| end | |
| def to_s = "#<Klass superclass: #{@superclass}>" | |
| alias_method :inspect, :to_s | |
| end | |
| self.superclass = superclass | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require "fiddle" | |
| module SettableSuperclass | |
| parent = Class.new | |
| child = Class.new(parent) | |
| child_pointer = Fiddle::Pointer.new(Fiddle.dlwrap(child)) | |
| SUPER_OFFSET = 0.step(by: Fiddle::SIZEOF_VOIDP, to: 160).find do | |
| child_pointer[it, Fiddle::SIZEOF_VOIDP].unpack1("J") == Fiddle.dlwrap(parent) | |
| end | |
| refine Kernel do | |
| def superclass=(new_super) | |
| raise TypeError, "new_super must be a Class, got: #{new_super.class}" unless new_super.instance_of?(Class) | |
| Fiddle::Pointer.write(Fiddle.dlwrap(self) + SUPER_OFFSET, [Fiddle.dlwrap(new_super)].pack("J")) | |
| end | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require_relative "klass" | |
| class Duck def quack = "Quack." end | |
| class Goose def honk = "Honk." end | |
| shapeshifter = Klass.new(Duck) | |
| shapeshifter.quack #=> "Quack." | |
| shapeshifter.superclass = Goose | |
| shapeshifter.honk #=> "Honk." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment