Skip to content

Instantly share code, notes, and snippets.

View havenwood's full-sized avatar
:octocat:

Shannon Skipper havenwood

:octocat:
  • Leafly
  • Ashland, Oregon
  • 03:46 (UTC -08:00)
View GitHub Profile
@havenwood
havenwood / curtain.rb
Created November 27, 2025 01:33
at_exit with priorities
module Curtain
@hooks = []
@order = 0
@mutex = Mutex.new
class << self
attr_reader :order
def register(group:, priority: 0, &block)
@mutex.synchronize do
@havenwood
havenwood / ruby_vm-shape.rb
Created November 15, 2025 19:38
A nicer interface to look at the Shape of a Ruby Object
require 'json'
require 'objspace'
class RubyVM
module Shape
def self.id(obj)
json = ObjectSpace.dump(obj, output: :string)
JSON.parse(json).fetch('shape_id')
end
@havenwood
havenwood / tags.rb
Created November 15, 2025 19:34
An example of ObjectSpace::WeakKeyMap, which was introduced in Ruby 3.3
require 'delegate'
class Tags < SimpleDelegator
def initialize = super(ObjectSpace::WeakKeyMap.new)
def tagged?(key) = key?(key)
end
TAGS = Tags.new
lamb = -> {}
@havenwood
havenwood / literalparser.rb
Created October 29, 2025 09:40 — forked from apeiros/literalparser.rb
Parse literals to ruby objects
require 'strscan'
require 'bigdecimal'
# This is copied and slightly refactored from BareTest::TabularData
#
# Example
# LiteralParser.parse("nil") # => nil
# LiteralParser.parse(":foo") # => :foo
@havenwood
havenwood / proc_to_lambda.rb
Last active November 5, 2025 04:50
An example showing how to convert a Proc into a lambda and vice versa with Fiddle
require 'fiddle'
module Procify
WORD = Fiddle::SIZEOF_VOIDP
RPROC_OFFSET = 4 * WORD
PROC_FLAG_OFFSET = 32
PROC_PACKED = [0].pack('Q').freeze
LAMBDA_PACKED = [2].pack('Q').freeze
refine Proc do
@havenwood
havenwood / papercraft.rb
Created October 14, 2025 18:51
My suggestion for a lambda-like strict arity alternative to a block
module Papercraft
class Block
def initialize(&) = singleton_class.define_method(:call, &)
def apply(...) = self.class.new { call(...) }
class HTML < Block
def render(...) = call(...)
def to_html = render.to_s
end
end
@havenwood
havenwood / options.rb
Created October 8, 2025 15:15
An example of `Ruby::Box` isolating globals (due to be released on Christmas)
class Options < Ruby::Box
def [](name) = instance_eval { eval "$#{name.to_s.delete_prefix('$')}" }
end
options = Options.new
options.instance_eval do
require 'optparse'
class Option
def []=(key, value)
@havenwood
havenwood / global_variable.rb
Created September 3, 2025 20:15
Set & get Ruby global variables using Fiddle
require 'fiddle'
require 'fiddle/import'
module GlobalVariable
extend Fiddle::Importer
dlload Fiddle::Handle::DEFAULT
extern 'void rb_gv_set(const char*, unsigned long)'
extern 'unsigned long rb_gv_get(const char*)'
end
@havenwood
havenwood / command.rb
Created August 2, 2025 19:20
Example io-stream for #ruby IRC
require 'io/stream'
require 'open3'
module Command
Result = Data.define(:out, :err, :status)
def self.run(*, **)
Open3.popen3(*, **) do |stdin, stdout, stderr, thread|
stdin.close
@havenwood
havenwood / document.rb
Last active June 30, 2025 17:27
Mixin example for #ruby IRC
module Document
def self.included(base)
base.class_eval do
def self.name = "#{super}ument"
end
end
module_function
def print = :printed