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!

February 15
spacer

pebble beach with woods and mickelson

January 5

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

November 6
spacer

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

October 10

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

October 2

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
September 4
spacer

ruby conference

August 20

Surfing in Glenwood Springs (I shot the video)

August 4
USGA Handicap Index Effective: 8/1/11 - 12.3 www.ghin.com/
June 7
spacer

What’s Your Start-up’s “Bus Count”? 7 Myths of Entrepreneurship and Programming

May 22
spacer

startup week in boulder/denver

April 24

Mizuno HttpServer

…couldn’t resist making a few changes to mizuno including an abstract handler, jmx suport, and slf4j logging. It’s just a placeholder for now…still fleshing out some new ideas.

module Mizuno
  class HttpServer
    include_class 'org.eclipse.jetty.server.Server'
    include_class 'org.eclipse.jetty.servlet.ServletContextHandler'
    include_class 'org.eclipse.jetty.servlet.ServletHolder'
    include_class 'org.eclipse.jetty.util.thread.QueuedThreadPool'
    include_class 'org.eclipse.jetty.servlet.DefaultServlet'
    include_class 'org.eclipse.jetty.jmx.MBeanContainer'
    include_class 'org.eclipse.jetty.server.Server'

    include_class 'java.lang.management.ManagementFactory'
    include_class 'javax.management.MBeanServer'

    include_class 'org.slf4j.Logger'
    include_class 'org.slf4j.LoggerFactory'

    @@logger = LoggerFactory.getLogger("HttpServer")

    def self.run(app, options = {})
      options = Hash[options.map { |option| [option[0].to_s.downcase.to_sym, option[1]] }]

      port = options[:port].to_i

      thread_pool = QueuedThreadPool.new
      thread_pool.min_threads = 5
      thread_pool.max_threads = 50

      rack_handler = RackHandler.new
      rack_handler.rackup(app)

      @server = Server.new(port)
      @container = MBeanContainer.new(ManagementFactory.getPlatformMBeanServer)
      @server.container.addEventListener(@container)
      @server.set_thread_pool(thread_pool)
      @server.set_handler(rack_handler)
      @server.start

      @@logger.info("Started jetty on port {}.", port)

      trap("SIGINT") { @server.stop and exit }

      @server.join unless options[:embedded]
    end

    def self.stop
      @server.stop

      @@logger.info("Stopper jetty.")
    end
  end
end

Rack::Handler.register 'mizuno', 'Mizuno::HttpServer'

+
my tungle profile

tungle.me/michaelbarinek

April 22
spacer

sporting a new haircut this afternoon, now time for a shave

April 15
spacer
gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.