Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

View soulcutter's full-sized avatar

Bradley Schaefer soulcutter

View GitHub Profile
@soulcutter
soulcutter / mailing_list.rb
Last active October 21, 2022 12:08
Dealing with crazy nested hashes in MailChimp API responses
require "delegate"
require "singleton"
module MailingList
class SafeResponse < SimpleDelegator
def self.safe_delegate(*methods)
methods.each do |method|
define_method(method, ->(*args, &block) {
value = __getobj__.send(method, *args, &block)
value ? SafeResponse.new(value) : BlackHole.instance
@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 / digest_auth.rb
Last active February 1, 2019 17:13
Faraday request middleware for digest auth
# -*- coding: utf-8 -*-
require 'faraday'
require 'net/http/digest_auth'
module Faraday
# Public: A Faraday middleware to use digest authentication. Since order of
# middlewares do care, it should be the first one of the Request middlewares
# in order to work properly (due to how digest authentication works).
#
# If some requests using the connection don't need to use digest auth you
@soulcutter
soulcutter / capyconsole.rake
Created May 5, 2014 14:53
Capyconsole rake task
desc "Launch a Capybara session in a console"
task capyconsole: :environment do
require "capybara"
require "pry"
driver = case ENV.fetch('DRIVER', 'phantomjs')
when 'phantomjs'
require "capybara/poltergeist"
Capybara.register_driver :poltergeist_debug do |app|
@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 }