barinek.com: the official website

Below you'll find a quick stream of consciousness that includes photos, quotes, code snippets, and possibly even a full post. enjoy!

There was once a man who became unstuck in the world – he realized that he was not his car, he realized that he was not his job, he was not his phone, his desk or his shoes. Like a boat cut from its anchor, he’d begin to drift. Castles in the Sky
the city museum

the city museum

ruby conference, 2012

ruby conference, 2012

ruby conference, 2011

ruby conference, 2011

Guice-ish

Playing around with dependency injection

require "singleton"
require "i18n"
require "active_support"
require "active_support/core_ext/string"

module Guice
  def inject(*klass_symbols)
    @injections = Hash.new unless @injections
    @injections[self.name] = klass_symbols
  end

  def injections
    @injections ||= Hash.new
    @injections[self.name] || []
  end

  class Injector
    include Singleton

    def self.configure_injector(&block)
      raise "Sorry, requires a block." unless block
      raise "Sorry, already configured." if instance.configured

      block.call(instance)
      instance.instance_variable_set(:@configured, true)
      instance
    end

    def initialize
      @known_bindings = Hash.new
      @known_instances = Hash.new
      !@configured
    end

    def configured
      @configured
    end

    def bind(klass)
      @known_bindings[klass.name] = klass
    end

    def get_instance(klass)
      raise "Sorry, not configured." unless @configured
      get_deep_instance(klass)
    end

    def get_deep_instance(klass, parents = [])
      instance = @known_instances[klass.name]
      return instance if instance

      if klass.kind_of?(Guice)
        parameters = klass.instance_method(:initialize).parameters.collect { |param| param[1] }
        if (parameters.eql?(klass.injections))
          parameter_instances = parameters.collect do |parameter|
            return nil if parents.include?(parameter.to_s.camelize.constantize)
            get_deep_instance(parameter.to_s.camelize.constantize, parents.push(klass))
          end
          raise "Sorry, possible circular dependency found." if parameter_instances.any? { |parameter_instance| parameter_instance.nil? }
          @known_instances[klass.name] = klass.new(*parameter_instances)
        end
      else
        begin
          @known_instances[klass.name] = klass.new
        rescue
          raise "Sorry, unknown constructor args."
        end
      end
      @known_instances[klass.name]
    end
  end
end

require "rspec"

describe Module do
  before(:all) do
    @injector = Guice::Injector.configure_injector do |injector|
      injector.bind(Foo)
      injector.bind(Bar)

      injector.bind(Cart)
      injector.bind(Horse)

      injector.bind(Fiz)
      injector.bind(Buz)
    end
  end

  it "can't be created" do
    lambda do
      Guice::Injector.new
    end.should raise_error
  end

  it "requires a block" do
    lambda do
      Guice::Injector.configure_injector
    end.should raise_error("Sorry, requires a block.")
  end

  it "complains about being configured twice" do
    lambda do
      Guice::Injector.configure_injector do |injector|
        injector.bind(Foo)
      end
    end.should raise_error("Sorry, already configured.")
  end

  it "injects bar" do
    foo = @injector.get_instance(Foo)
    foo.bar.should be
  end

  it "complains about circular dependencies" do
    lambda { @injector.get_instance(Cart) }.should raise_error("Sorry, possible circular dependency found.")
    lambda { @injector.get_instance(Horse) }.should raise_error("Sorry, possible circular dependency found.")
  end

  it "complains about unknown constructor args" do
    lambda { @injector.get_instance(Fiz) }.should raise_error("Sorry, unknown constructor args.")
  end

  class Foo
    extend Guice

    inject :bar

    def initialize(bar)
      @bar = bar
    end

    def bar
      @bar
    end
  end

  class Bar
  end

  class Cart
    extend Guice

    inject :horse

    def initialize(horse)
    end
  end

  class Horse
    extend Guice

    inject :cart

    def initialize(cart)
    end
  end

  class Fiz
    extend Guice

    inject :buz

    def initialize(buz)
    end
  end

  class Buz
    def initialize(bop)
    end
  end
end



morning in San Juan

morning in San Juan

The new ride

The bitterness of poor quality remains long after the sweetness of low price is forgotten benjamin franklin
pebble beach with woods and mickelson

pebble beach with woods and mickelson

Stopwatch


require 'singleton'

module Stopwatch

  if defined?(ActiveRecord) && defined?(ActiveRecord::ConnectionAdapters)
    ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval do
      def log_with_watcher(sql, name = "SQL", binds = [], &block)
        Stopwatch.instance.event("sql '#{name}'.") do
          log_without_watcher(sql, name, binds, &block)
        end
      end

      alias_method_chain :log, :watcher
    end
  end

  if defined?(ActionController)
    ActionController::Base.class_eval do
      def render_with_watcher(*args, &block)
        Stopwatch.instance.event("render.") do
          render_without_watcher(*args, &block)
        end
      end

      alias_method_chain :render, :watcher
    end
  end

  def self.watch(&block)
    watcher = Watcher.instance
    running = watcher.running
    watcher.start
    response = yield watcher
    watcher.stop unless running
    response
  end

  def self.instance
    Stopwatch::Watcher.instance
  end

  def self.reset
    Stopwatch::Watcher.instance.reset
  end

  class Split
    attr_reader :time, :message

    def initialize(time, message)
      @time = time
      @message = message
    end
  end

  class Event
    attr_reader :duration, :message

    def initialize(duration, message)
      @duration = duration
      @message = message
    end
  end

  class Tally
    attr_reader :duration, :message, :count

    def initialize(message)
      @message = message
      @duration = 0.0
      @count = 0.0
    end

    def add(event)
      @duration += event.duration
      @count += 1
    end
  end

  class Watcher
    include Singleton

    attr_reader :running, :splits, :events

    def initialize
      @running = false
      @splits = []
      @events = []
    end

    def start
      return if @running
      reset
      @running = true
      @start = Time.now
      puts "\n[stopwatch @time=#{human_time(0.0)}] started."
    end

    def stop
      @stop = Time.now
      @running = false
      puts "[stopwatch @time=#{human_time(@stop - @start)}] stopped."
    end

    def reset
      @running = false
      @splits = []
      @events = []
    end

    def split(message)
      split_time = Time.now
      @splits.push Split.new(split_time, message)
    end

    def event(message)
      start = Time.now
      result = yield
      stop = Time.now
      duration = stop - start
      @events.push Event.new(duration, message) if @running
      result
    end

    def report
      report_splits
      report_events
    end

    private

    def report_splits
      last_time = nil
      @splits.each do |split|
        time = split.time
        message = split.message
        elapsed = last_time ? time - last_time : time - @start
        last_time = time
        puts "[stopwatch @time=#{human_time(elapsed)}] split #{message} "
      end unless @splits.empty?
    end

    def report_events
      tallies = {}
      @events.each do |event|
        tallies[event.message] = Tally.new(event.message) unless tallies[event.message]
        tallies[event.message].add(event)
      end
      tallies.each do |key,tally|
        puts "[stopwatch @time=#{human_time(tally.duration)}] event #{tally.message} (#{tally.count.to_i})"
      end
    end

    def human_time(time)
      "%.2fms" % (time * 1_000)
    end

  end

end



require "test/unit"

require File.expand_path(File.join(File.dirname(__FILE__), "stopwatch"))

class TestStopwatch  Test::Unit::TestCase

  class ExampleLogger
    include Singleton

    def log(message)
      p message
    end

    def self.alias_method_chain(target, feature)
      alias_method "#{target}_without_#{feature}", target
      alias_method target, "#{target}_with_#{feature}"
    end
  end

  ExampleLogger.class_eval do
    def log_with_test(message, &block)
      Stopwatch.instance.event("a") do
        log_without_test(message, &block)
      end
    end

    alias_method_chain :log, :test
  end

  def setup
    Stopwatch.reset
  end

  def test_watch
    assert(!Stopwatch.instance.running)
    Stopwatch.watch do
      assert(Stopwatch.instance.running)
    end
    assert(!Stopwatch.instance.running)
  end

  def test_splits
    Stopwatch.watch do |watcher|
      watcher.split("a")
      watcher.split("b")
      watcher.split("c")
    end
    assert_equal(Stopwatch.instance.splits.size, 3)
    assert_equal(Stopwatch.instance.splits.collect { |split| split.message }, ["a", "b", "c"])
  end

  def test_nested
    Stopwatch.watch do |watcher|
      watcher.split("a")
      Stopwatch.watch do |watcher|
        watcher.split("b")
      end
      assert(Stopwatch.instance.running)
    end
    assert_equal(Stopwatch.instance.splits.size, 2)
    assert_equal(Stopwatch.instance.splits.collect { |split| split.message }, ["a", "b"])
  end

  def test_split_report
    Stopwatch.watch do |watcher|
      watcher.split("a")
      watcher.split("b")
      watcher.split("c")
      watcher.report
    end
  end

  def test_events
    Stopwatch.watch do |watcher|
      ExampleLogger.instance.log("message")
      Stopwatch.instance.event("b") do
      end
    end
    assert_equal(Stopwatch.instance.events.size, 2)
    assert_equal(Stopwatch.instance.events.collect { |event| event.message }, ["a", "b"])
  end

  def test_no_events
    Stopwatch.watch do |watcher|
    end
    ExampleLogger.instance.log("message")
    Stopwatch.instance.event("b") do
    end
    assert_equal(Stopwatch.instance.events.size, 0)
  end

end

Winter Golf in Aspen

Winter Golf in Aspen

Simple Trie for Autocomplete


require 'test/unit'

class Trie
  def initialize()
    @root = TrieNode.new
    @entry_count = 0
  end

  def empty?
    @entry_count == 0;
  end

  def size
    @entry_count
  end

  def add(key, value)
    return if key.nil? || key.empty?

    current_node = @root
    key.each_char { |character|
      next_node = current_node.get(character)
      next_node = current_node.add(character) unless next_node
      current_node = next_node
    }
    current_node
    current_node.value = value
    @entry_count += 1
  end

  def contains(str)
    # todo...
  end

  def find(string)
    results = []
    (0..string.length-1).each { |start_index|
      start_index
      current_node = @root
      (start_index..string.length-1).each { |i|
        ch = string[i].chr
        current_node = current_node.get(ch)
        break if current_node.nil?
        results.push current_node.values if current_node.values?
      }
    }
    results
  end

  class TrieNode
    def initialize()
      @children = Hash.new
    end

    def value=(value)
      if (@values.nil?)
        @values = Array.new
      end
      @values.push value
    end

    def get(character)
      @children[character]
    end

    def add(character)
      node = TrieNode.new
      @children[character] = node
      node
    end

    def values
      @values
    end

    def values?
      !@values.nil?
    end
  end
end

class TriTest  Test::Unit::TestCase
  def test_empty?
    trie = Trie.new
    assert(trie.empty?)

    trie.add("key", "value")
    assert(!trie.empty?)
  end

  def test_size
    trie = Trie.new
    trie.add("key", "value")
    assert_equal(1, trie.size)
  end

  def test_ignores_nil_or_empty_string
    trie = Trie.new
    trie.add("", "value")
    trie.add(nil, "value")
    assert(trie.empty?)
  end

  def test_find
    trie = Trie.new
    trie.add("key", "value")
    assert_equal(1, trie.find("key").size)

    trie.add("keys", "value")
    assert_equal(2, trie.find("keys").size)
  end

  def test_allows_duplicates
    trie = Trie.new
    trie.add("key", "value")
    trie.add("key", "value")
    assert(!trie.empty?)
  end
end

Handy Git Commands

source /usr/local/etc/bash_completion.d/git-completion.bash 

alias gits="git status"

git add -p

[alias]
	staged = diff --cached

[color]
        status = auto
        branch = auto
        diff = auto