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!

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

Chris’s Reading List

C

  • C Programming Language (2nd Edition) by Brian W. Kernighan and Dennis M. Ritchie
Java
  • Java Programming Language, The (4th Edition) by Ken Arnold, James Gosling and David Holmes
  • Thinking in Java (4th Edition) by Bruce Eckel
  • Advanced Effective Java (2nd Edition) by Joshua Bloch
  • Advanced Java Concurrency in Practice by Brian Goetz, Tim Peierls, Joshua Bloch and Joseph Bowbeer
Ruby
  • Learn to Program, Second Edition (The Facets of Ruby Series) by Chris Pine
  • Programming Ruby 1.9: The Pragmatic Programmers’ Guide (Facets of Ruby) by Dave Thomas, Chad Fowler and Andy Hunt
Algorithms
  • Algorithms in Java, Parts 1-4 (3rd Edition) (Pts.1-4) by Robert Sedgewick
Testing
  • Test Driven Development: By Example by Kent Beck
Software Design Advanced
  • Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides
  • Refactoring: Improving the Design of Existing Code by Martin Fowler, Kent Beck, John Brant and William Opdyke
  • Refactoring to Patterns by Joshua Kerievsky
The Enterprise Advanced
  • Patterns of Enterprise Application Architecture by Martin Fowler
  • Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions by Gregor Hohpe and Bobby Woolf
Web
  • Agile Web Development with Rails (Pragmatic Programmers) by Sam Ruby, Dave Thomas and David Heinemeier Hansson
  • Advanced Restful Web Services by Leonard Richardson, Sam Ruby and David Heinemeier Hansson
Methodology
  • Extreme Programming Explained: Embrace Change (2nd Edition) by Kent Beck and Cynthia Andres
  • Agile Software Development with Scrum (Series in Agile Software Development) by Ken
  • Schwaber and Mike Beedle
SQL
  • Joe Celko’s SQL for Smarties, Fourth Edition: Advanced SQL Programming (The Morgan Kaufmann Series in Data Management Systems) by Joe Celko
37 Signals
  • Rework by Jason Fried and David Heinemeier Hansson
  • Getting Real: The smarter, faster, easier way to build a successful web application by Jason Fried, Heinemeier David Hansson and Matthew Linderman
Collections
  • Pragmatic Unit Testing in Java with JUnit by Andy Hunt and Dave Thomas
  • Pragmatic Project Automation: How to Build, Deploy, and Monitor Java Apps by Mike Clark
  • Pragmatic Version Control Using Git (Pragmatic Starter Kit) by Travis Swicegood
Pragmatism
  • The Pragmatic Programmer: From Journeyman to Master by Andrew Hunt and David Thomas
whisky tour - http://whiskygeeks.com/

Surfing in Glenwood Springs (I shot the video)

USGA Handicap Index Effective: 8/1/11 - 12.3 http://www.ghin.com/