Skip to content

Instantly share code, notes, and snippets.

View soulcutter's full-sized avatar

Bradley Schaefer soulcutter

View GitHub Profile
@soulcutter
soulcutter / otherwise_enumerable.rb
Created October 31, 2024 17:37
Enumerating... or else
# Written based on a conversation about enumerating with behavior for
# empty collections
#
# https://ruby.social/@pushcx/113397079757804801
# https://www.justinweiss.com/articles/each-dot-dot-dot-or-else/
module OtherwiseEnumerable
refine Enumerable do
def otherwise
return yield if empty?
@soulcutter
soulcutter / memoize.rb
Created January 24, 2022 14:33
Memoizing in Ruby without ivars and defined?
class Memoizer < Module
def initialize(method_name)
define_method(method_name) do
super().tap do |value|
puts "memoizing"
define_singleton_method(method_name) { value }
end
end
end
end
@soulcutter
soulcutter / test.rb
Created March 8, 2019 18:36
create_or_find_by sequence exhaustion
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "rails", github: "rails/rails"
@soulcutter
soulcutter / speed_limit.rb
Created April 8, 2018 21:09
A simple way to throttle enumeration
class SpeedLimit
def initialize(enumerator)
@enumerator = enumerator.to_enum
end
def at(count, per:)
increment_seconds = case per
when :second then 1.0 / count.to_f
when :minute then 60.0 / count.to_f
when :hour then 3600.0 / count.to_f
@soulcutter
soulcutter / tapper.rb
Created March 9, 2018 14:37
Tap vs Local Variables
def level_descriptions=(input)
write_attribute(:levels_description, input).tap do |_result|
flush_cache :levels_description
end
end
# same number of lines, one less method call, one less block, but pretty much the same as
# far as I'm concerned.
def level_descriptions=(input)
result = write_attribute(:levels_description, input)
@soulcutter
soulcutter / memoize_example.rb
Created March 1, 2018 20:57
A memory-leaking memoization implemenation inspired by https://twitter.com/PragTob/status/969292754294583297
module Memo
def memoize(method_name)
original_method = instance_method(method_name)
method_cache = Hash.new { |h, k| h[k] = {} }
define_method(method_name) do |*args, &block|
if method_cache[self].key?([args, block])
method_cache[self][[args, block]]
else
method_cache[self][[args, block]] = original_method.bind(self).call(*args, &block)
end
@soulcutter
soulcutter / instrumentor.rb
Created November 14, 2017 19:28
Instrumentation for methods
module Instrumenter
class Instrumentation < Module
def initialize(method, label)
@method = method
@label = label
define_method(method) do |*args|
start_time = Time.now
super(*args).tap do
end_time = Time.now
@soulcutter
soulcutter / urinal_game.rb
Last active November 5, 2017 18:00
Example of what object syntax could look like
bathroom.urinals.occupied.select { |urinal| urinal.adjacent.select(&:occupied?).any? }
Urinal = Struct.new(:is_occupied, :location) { def adjacent_urinals; location.adjacent_urinals; end }
require "delegate"
Foo = Class.new(SimpleDelegator)
Bar = Struct.new(:foo)
Foo.new(1) == Foo.new(1) # => true
Bar.new(1) == Bar.new(1) # => true
Foo.new(Bar.new(1)) == Foo.new(Bar.new(1)) # => false
@soulcutter
soulcutter / bounded_hash.rb
Created October 3, 2016 21:47
A bounded hash that expires keys using LRU (roughly)
# frozen_string_literal: true
require "delegate"
require "set"
# Hash that can only hold a certain number of keys, keys expire on a LRU basis
class BoundedHash < DelegateClass(Hash)
NO_OP = proc {}