Skip to content

Instantly share code, notes, and snippets.

View pmarreck's full-sized avatar

Peter Marreck pmarreck

  • formerly senior engineer @ desk.com, chief engineer @ thredup.com, software engineer @ lifebooker.com. Director of Engineering @ addigence.com, currently available
  • Long Island, NY
  • 04:36 (UTC -04:00)
  • X @pmarreck
  • LinkedIn in/petermarreck
View GitHub Profile
@pmarreck
pmarreck / assign_value_only_once_hash.rb
Created March 7, 2013 22:16
Ruby hash that allows value assignment by key only once
class AssignValueOnlyOnceHash < Hash
KeyReassignmentError=Class.new(RuntimeError)
def []=(key, val)
raise KeyReassignmentError, "key '#{key}' already assigned" if key? key
super
end
end
if __FILE__==$PROGRAM_NAME
require 'test/unit'
@pmarreck
pmarreck / ruby_hash_key_nondeterminism.rb
Last active December 15, 2015 04:59
Why Ruby hash key format ambiguity is dangerous.
>> require 'active_support/all'
=> true
>> hwia = HashWithIndifferentAccess[:a, 1, :b, 2]
=> {:a=>1, :b=>2} # uh... ok so maybe they didn't define self.[]= . but all is not lost... yet. let's continue.
>> hwia
=> {:a=>1, :b=>2} # well, they're supposed to always be strings internally, but let's try anyway
>> hwia['a']
=> nil # ORLY.
>> hwia.merge!({:a => 11, 'a' => 12})
=> {:a=>1, :b=>2, "c"=>3, "a"=>12} # For fuck's sake.
@pmarreck
pmarreck / ruby_runtime_profiling.rb
Last active December 15, 2015 10:29
I wanted an easy way to profile the memory usage of Ruby code on-the-fly, from anywhere. So I wrote this. It returns the number of new objects, their sizes (if available; I don't yet have a generic way to determine this), and any time consumed (wall clock; i'd love to figure out process ute in a platform-agnostic way). Optionally, you can hook i…
class HashList < Hash
def add(k)
self[k] = true
end
alias include? key?
end
module ResourceConsumptionProfiler
extend self
def profile_resource_consumption(params = {})
@pmarreck
pmarreck / mutable_mayhem.rb
Last active December 15, 2015 19:29
Beware of mutable constants in Ruby!
# Observe:
class MyAwesomeToDos
ALLOWED_THINGS = [:beer, :whiskey, :women, :clean_code] #.freeze
def initialize(params)
@params = params
end
def allowed_things
@pmarreck
pmarreck / deep_hash_to_deep_openstruct.rb
Last active January 26, 2018 18:08
Convert a deep hash to a deep openstruct. There is a gem which tries to do this already, but it's dumb. ;)
require 'ostruct'
module HashToOpenstruct
def to_ostruct
o = OpenStruct.new(self)
each.with_object(o) do |(k,v), o|
o.send(:"#{k}=", v.to_ostruct) if v.respond_to? :to_ostruct
end
o
end
end
@pmarreck
pmarreck / encrypt_decrypt.sh
Last active September 23, 2021 20:18
Some easy bash scripts to encrypt/decrypt data, for anyone who wants to go all cloak&dagger. (bitcoin private keys, etc.)
# Encryption functions. Requires the GNUpg "gpg" commandline tool. On OS X, "brew install gnupg"
# Explanation of options here:
# --symmetric - Don't public-key encrypt, just symmetrically encrypt in-place with a passphrase.
# -z 9 - Compression level
# --require-secmem - Require use of secured memory for operations. Bails otherwise.
# cipher-algo, s2k-cipher-algo - The algorithm used for the secret key
# digest-algo - The algorithm used to mangle the secret key
# s2k-mode 3 - Enables multiple rounds of mangling to thwart brute-force attacks
# s2k-count 65000000 - Mangles the passphrase this number of times. Takes over a second on modern hardware.
# compress-algo BZIP2- Uses a high quality compression algorithm before encryption. BZIP2 is good but not compatible with PGP proper, FYI.
@pmarreck
pmarreck / ruby_gc_profile.sh
Created April 25, 2013 19:50
More sensible Ruby GC env configs for medium to large Rails stacks (Sourced from Twitter's and 37Signals' configs)
# Ruby environment tweaking
export RUBY_HEAP_MIN_SLOTS=1000000
export RUBY_HEAP_SLOTS_INCREMENT=1000000
export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
export RUBY_GC_MALLOC_LIMIT=100000000
export RUBY_HEAP_FREE_MIN=500000
@pmarreck
pmarreck / post_fork_global_state_freeze_motherfucker.rb
Last active December 17, 2015 07:19
If you're having fork problems, I feel bad for you, son...
# ...I got 99 problems, but after this, fork and thread safety won't be one...
module Process
alias fork_without_freeze fork
def fork_with_freeze(&block)
result = fork_without_freeze(&block)
ObjectSpace.each_object(Class){|c| c.freeze }
result
end
alias fork fork_with_freeze
@pmarreck
pmarreck / every_2factor_auth_everywhere.rb
Created May 14, 2013 14:16
So as a morning exercise I implemented the core of all of the following in about 10 lines of Ruby: The Google Authenticator app, the RSA SecurID app, the Yubikey, the Blizzard Authenticator, and pretty much every other 2-factor-auth pre-shared-secret scheme I can think of.
#!/usr/bin/env ruby
require 'digest/sha2'
shared_secret = "yabbadabbadoo"
provider_salt = "peter"
seconds_since_epoch = Time.now.to_i
minutes_since_epoch = seconds_since_epoch / 60
cleartext = shared_secret + provider_salt + minutes_since_epoch.to_s
hash = Digest::SHA2.new << cleartext
@pmarreck
pmarreck / directory_digest.rb
Created June 3, 2013 22:52
Detect file changes in a directory recursively.
require 'digest/sha1'
Dir.glob("**/api/v2/**/*.rb").inject(0){|acc,f| acc ^ Digest::SHA1.hexdigest(File.read(f)).to_i(16) }