Joe MooreJoe Moore
What Is Your Workstation Tag?
edit Posted by Joe Moore on Thursday March 19, 2009 at 12:55AM

At Pivotal, we love our large, shared workspace and homogeneous workstations. As we move from project to project, our workstations are pretty much the same: iMacs with TextMate, RubyMine, Quicksilver (bound to ⌘+space, of course!) a full Ruby/Rails stack, and a few other applications. Given this minimal setup, I can figure out which developers have used a particular workstation given the extra applications installed upon it. I've come to see certain applications as a developer's "tag," like a graffiti signature.

As for me, if you see Jumpcut and Skitch, then I've tagged your machine.

What are your tags?

Joe MooreJoe Moore
How To Create a Fluid Application for Pivotal Tracker
edit Posted by Joe Moore on Saturday January 31, 2009 at 11:48PM

http://assets.pivotallabs.com/258/original/trackerscreen.jpg

As a developer of web apps, I'm inevitably running 3 or 4 browsers, each with 10 tabs open containing my application under development, Google searches, gotapi (pronounced "got a pie?" of course!), design wireframes, and all kinds of other very important stuff. And in one of those tabs, somewhere, is Pivotal Tracker. Browsers and tabs are great, but sometimes you just want an Application -- notice the capital "A."

Fluid to the rescue! Fluid lets you create Site Specific Browsers, which "provide a great solution for your WebApp woes." In a nutshell, Fluid makes a custom WebKit browser that, when launched, opens just the site you configured it to open, such as Gmail, Pandora, or even Pivotal Tracker. I love that I can maximize the Pivotal Tracker app and boost the font 3 or 4 levels, filling a screen with Tracker goodness without the clutter or navigation buttons, bookmark bars, or tabs. And where is Tracker? Just command-tab!

http://assets.pivotallabs.com/262/original/command_tab_2.jpg

Here's how to create a Fluid application for Pivotal Tracker.

  1. Download and install Fluid
  2. Download the Fluid Icon for Pivotal Tracker
  3. Launch Fluid
  4. Enter the following:
    • URL: http://www.pivotaltracker.com
    • Name: Pivotal Tracker
    • Location: pick one!
    • Icon: pick 'Other...' then find the tracker icon you downloaded earlier http://assets.pivotallabs.com/255/original/screen_149.png
  5. Click Create, then launch it!

Once launched, open the Pivotal Tracker preferences and change the Window Style to "HUD (Black)" under Appearance Preferences Why? Because it looks cool.

http://assets.pivotallabs.com/259/original/twomonitors.jpg

Update

Here is the Fluid icon, upon request.

http://assets.pivotallabs.com/264/original/tracker.png

Nick KallenNick Kallen
The Law of Demeter is a Piffle
edit Posted by Nick Kallen on Wednesday May 07, 2008 at 09:15PM

One of The Blabs' most controversial articles was Lovely Demeter, Meter Maid, in which Pivotal and Thoughtworks battle over which Agile consultancy has the better understanding of the Law of Demeter, and which has better hair and music taste (seriously).

I have never found this "law" very persuasive.

  • The bizarre, culturally loaded analogy about a paperboy and a wallet says nothing insightful about encapsulation boundaries as they arise in real software systems.
  • The blogosphere's endless scholastic hermeneutics of the law's 4 allowances for message sending is a masturbatory philosophical enterprise with nothing relevant to real-world software.
  • The Mockist's insistence on easy mockability is of dubious merit--build better mocking frameworks!
  • And the few practical, real merits that arise in from following the Law of Demeter are better arrived at using other techniques, such as "Tell, Don't Ask".

Here Are Two Examples, one where I violate the Law of Demeter, and another where I don't.

I wrote this code recently, in flagrant violation of the Law:

cookies[:store_id] = @login.store.id

Suppose @login is not an ActiveRecord object, it does not automatically have a #store_id method. Should I create a delegator for this?

class Login
  def store_id
    store.id
  end
end

This is pretty silly. The store_id is not an attribute of the login; rather it's an attribute of the store, and the store is an attribute of the login. The delegator is needless code cruft to replace a dot with an underscore, it smells of the endless boilerplate Java code of my youth. Demeter be damned.

On the other hand, here is a refactoring I did, incidentally complying with the law of Demeter:

Here is the original, Demeter-violating code:

def find_attribute_given_name(name)
  attributes.detect { |a| a.name_or_alias == name }
end

The call to == here is the violation of Demeter. I later replaced this with:

attributes.detect { |a| a.named?(name) }

The latter complies with the "law". And it's much better code. But was I lead to the improvement to this by Demeter? No, I was lead to it by a better understanding of the encapsulation boundaries of the object (#name_or_alias became private) and by a desire to have my code be more terse and clear. a.named?(name) is the most terse explanation of the intended computation that I can think of.

Demeter be damned.

Nick KallenNick Kallen
Ruby Pearls vol. 1 - The Splat
edit Posted by Nick Kallen on Wednesday April 23, 2008 at 05:03AM

Over the next week or so I'll be sharing Ruby idioms and flourishes that I quite like. Today I'd I'll show a few tiny uses of splat! that make me tremble with delight.

Splat! - For Beginners

Splat! is the star (*) operator, typically used in Ruby for defining methods that take an unlimited number of arguments:

def sprintf(string, *args)
end

It can also be used to convert an array to the multiple-argument form when invoking a function:

some_ints = [1,2,3]
sprintf("%%i %%i %%i", *some_ints)

Splat! - For Wizards

Array to Hash Conversion

The best use of splat! for invoking a infinite-arity functions I've ever seen is the recipe for converting an array to a hash. Suppose you have an array of pairs:

array = [[key_1, value_1], [key_2, value_2], ... [key_n, value_n]]

You would like to produce from it the hash: {key1 => value1 ... } You could inject down the array, everybody loves inject, but there is a better way:

Hash[*array.flatten]

Amazing right? This relies on the the fact that the Hash class implements the [] (brackets) operator and behaves thusly:

Hash[key1, value1, ...] = { key1 => value1, ... }

Heads or tails?

Splat! can be used for more than just method definition and invocation. My personal favorite use is destructuring assignment. I read this in Active Record's source code recently:

  def sanitize_sql_array(ary)
    statement, *values = ary
    ...
  end

This is invoked when you do something like User.find(:all, :conditions => ['first_name = ? and last_name = ?', 'nick', 'kallen']). Splat! is used here is to get the head and tail of the conditions array. Of course, you could use always use shift, but the functional style used here is quite beautiful. Consider another example:

first, second, *rest = ary

One final trivium (#to_splat aka #to_ary)

You can actually customize the behavior of the splat operator. In Ruby 1.8, implement #to_ary and in 1.9 it's #to_splat. For example

class Foo
  def to_ary
    [1,2,3]
  end
end

a, *b = Foo.new
a # => 1
b # => [2,3]

This also works for method invocation:

some_method(*Foo.new) == some_method(1,2,3)

When I first learned this at RubyConf I thought this was mind-blowing. I have since never used it.

Nick KallenNick Kallen
Ninja Patching jQuery
edit Posted by Nick Kallen on Tuesday April 01, 2008 at 11:23PM

Jonathan and I love jQuery's extended psuedo-selectors:

  • :input - Matches all input, textarea, select and button elements.
  • :text - Matches all input elements of type text.
  • :password - Matches all input elements of type password.
  • :hidden - Matches all elements that are hidden, or input elements of type * "hidden".
  • :visible - Matches all elements that are visible.
  • and so on

These aren't actually part of the CSS spec, but they're incredibly useful and can be chained:

$(':input:visible') // => finds all visible inputs

We wanted to customize the behaviors of :text and :visible:

  • We wanted :text to return both <input type="text"> AND <textarea>
  • We wanted :visible to return elements that aren't directly display:none or visibility:hidden, nor are their parents display:none or visibility:hidden

So, we decided to customize this behavior:

jQuery.extend(jQuery.expr[":"], {
  text    : "(a.tagName=='INPUT' && a.type=='text') || (a.tagName=='TEXTAREA')",
  visible : '"hidden"!=a.type && jQuery.css(a,"display")!="none" && jQuery.css(a,"visibility")!="hidden" && (jQuery(a).parent(":hidden").size() == 0)',
  hidden  : 'document != a && ("hidden"==a.type || jQuery.css(a,"display")=="none" || jQuery.css(a,"visibility")=="hidden" || (jQuery(a).parent(":hidden").size() > 0))'
});

So how would you like to ninja-patch jQuery's custom pseudo-selectors?

Nick KallenNick Kallen
Making Ruby Look Like Smalltalk Haskell Erlang Ruby
edit Posted by Nick Kallen on Sunday December 09, 2007 at 04:49AM

As Seen on TV

Inspired by Haskell

Did you ever want to write Ruby Code like:

x = 1
increment(x).by(6)

Now you can:

def increment(variable)
  chain do
    by do |delta|
      variable + delta
    end
  end
end

This is an OO version of a technique called Currying:

g = 'hello world'.index_of('o')
h = g.starting_at(6)

Inspired by Smalltalk:

'hello world' indexOf: $o startingAt: 6

Let's do this in Ruby:

class String
  def index_of(substring)
    chain do
      starting_at do |starting_at|
        ...
      end
    end
  end
end

Now, in Ruby:

'hello world'.index_of('o').starting_at(6)

Inspired by Erlang

Here is pseudo-code for an interesting iteration pattern. If the Actor receives 'lock' it will not respond to any messages until it receives 'unlock':

loop(X) ->
  receive
    'incr' -> loop(X+1)
    'lock' ->
      receive
        'unlock' ->
          loop(X);
      end
  end.

The Ruby equivalent:

def loop(x)
  puts x # added puts just to see what's going on
  chain do
    incr do
      loop(x+1)
    end
    lock do
      unlock do
        loop(x)
      end
    end
  end
end

Try this:

loop(1).incr.incr.incr => prints 1, 2, 3, then 4

Now, the finale: We can respond to incr any number of times till we're locked; then, we respond to no messages other than unlock; once we've received unlock we proceed as before.

loop(1).incr.lock.incr => prints 1, 2, then raises an exception.
loop(1).incr.lock.unlock.incr => prints 1, 2, then 3

How does this work?

The call to chain do ... end creates a new Chain object with the block passed in to the constructor. Chain is kind of "blank slate": all methods inherited from Object are undefined so that any messages it receives go through method missing. The block the Chain is instantiated with is instance-eval'd in the chain's context, and all method invocations go through method missing (because of the blank slate). Method missing has two cases. It either dynamically defines a method returning a new link in the Chain (in the case of nested chaining), or it delegates the method back to the object that constructed the chain in the first place. Let's consider examples of these two cases.

Case 1, dynamically defining a new method:

def foo
  chain do
    a do # define a method named :a on the Chain.
      1
    end
  end
end

foo.a => 1

Case 2, delegating the method back the the creator of the Chain:

def bar
  1
end

def foo
  chain do
    a do
      bar # invokes the bar defined above
    end
  end
end

foo.a => 1

Nested chaining is just a variation on Case 1:

def foo
  chain do
    a do
      b do # create a nested Chain (i.e., a Link)
        1
      end
    end
  end
end

foo.a.b => 1

The only gotcha is knowing whether a method invoked with a block belongs to the object that created the chain or is a nested chain:

def b(&block)
end

def foo
  chain do
    a do
      b do # is this the above b, or a nested Chain?
        ... 
      end
    end
  end
end

We prioritize the #b defined on the parent object, rather than created a nested chain (I feel this is more intuitive).

Here is the source code:

require 'rubygems'
require 'active_support'

class Chain
  instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|^instance_exec$)/ }
  delegate :define_method, :respond_to, :to => :__caller
  attr_accessor :__caller

  def __has_links?
    @__has_links
  end

  def initialize(*args, &block)
    if block_given?
      self.__caller = eval("self", block.binding)
      instance_exec *args, &block
    end
  end

  def method_missing(method, *args, &block)
    if block_given? && !__caller.respond_to?(method)
      @__has_links = true
      metaclass.module_eval do
        define_method method do |*args|
          __link(*args, &block)
        end
      end
    else
      __caller.send(method, *args, &block)
    end
  end

  private
  def __link(*args, &block)
    link = Chain.new
    link.__caller = __caller
    result = link.instance_exec(*args, &block)
    link.__has_links?? link : result
  end

  def metaclass
    class << self
      self
    end
  end
end

def chain(&block)
  Chain.new &block
end

Alex ChaffeeAlex Chaffee
Bush Violates Standup Rules
edit Posted by Alex Chaffee on Sunday November 04, 2007 at 08:29PM

Courtesy of Steve C and Alex Tabarrok

There is no "W" in "team"

There is no "W" in "team"

Alex ChaffeeAlex Chaffee
Rails Conference Links
edit Posted by Alex Chaffee on Monday May 21, 2007 at 08:30PM

(Blabbers who were at the conference, feel free to add your links to this post.)

Alex ChaffeeAlex Chaffee
Beer Night PDX
edit Posted by Alex Chaffee on Saturday May 19, 2007 at 10:59PM

front back

Alex ChaffeeAlex Chaffee
Extra Action
edit Posted by Alex Chaffee on Saturday May 19, 2007 at 10:32PM

It was fate. A crew of Pivots in Portland on the same weekend as the Extra Action Marching Band We just had to seize the opportunity...

Will they be making an appearance at our Beer Night tonight? You never know...

Other articles: