Posts from jvoorhis...

Aliasing Global Variables in Ruby

And while I am becoming quite the language lawyer, I should mention that Ruby’s alias statement treats global variables quite differently from other kinds of variables.

When aliasing global symbols, the global variable itself is aliased and not evaluated. The result is a true alias, not a copy, so you cannot modify the global and its alias independently.

This feature most likely exists solely for English.rb in the standard library. This being the case, see that file for examples.

Ruby's Hidden do {} while () Loop

I found the following snippet while reading the source for Tempfile#initialize in the Ruby core library:

begin
  tmpname = File.join(tmpdir, make_tmpname(basename, n))
  lock = tmpname + '.lock'
  n += 1
end while @@cleanlist.include?(tmpname) or
  File.exist?(lock) or File.exist?(tmpname)
At first glance, I assumed the while modifier would be evaluated before the contents of begin...end, but that is not the case. Observe:

>> begin
?>   puts "do {} while ()" 
>> end while false
do {} while ()
=> nil
As you would expect, the loop will continue to execute while the modifier is true.

>> n = 3
=> 3
>> begin
?>   puts n
>>   n -= 1
>> end while n > 0
3
2
1
=> nil
While I would be happy to never see this idiom again, begin...end is quite powerful. The following is a common idiom to memoize a one-liner method with no params:

def expensive
  @expensive ||= 2 + 2
end
Here is an ugly, but quick way to memoize something more complex:

def expensive
  @expensive ||=
    begin
      n = 99
      buf = "" 
      begin
        buf << "#{n} bottles of beer on the wall\n" 
        # ...
        n -= 1
      end while n > 0
      buf << "no more bottles of beer" 
    end
end

Urlang

Some weeks ago, after discovering Rack, I took it upon myself to experiment with my own anti-framework in Ruby, using existing libraries whenever possible and filling in the blanks as I go. A vital piece of most web frameworks is the dispatcher – the module that delegates web requests to application code.

The basic premise of my design is to encode common data structures within the path of a url, and to lookup the appropriate action in a dispatch table. I don’t have a working dispatcher yet, but I do have this:

irb(main):002:0> UrlParser.parse("/foo/1,2,3/meep=fleem;fliffl=mumble,grumble/")
=> [["foo"], ["1", "2", "3"], {"meep"=>["fleem"], "fliffl"=>["mumble", "grumble"]}]

The simple language uses a slash to separate values, a comma to group them into a list, and equals and semi-colon together to create a hash. The values are returned as a list.

The next step is to determine the semantics of how an action is selected. My tastes would be satisfied by a very simple form of pattern matching, with this approximate syntax, mixing literals and types:

register(:module => PostsController, :action => :show,
         :path => ['posts', Integer], :method => GET)

Further refinements to the path language might include recognizing ints and floats, and distinguishing between array and scalar values.

If you find the idea interesting, or even terrible, I’d love to hear your thoughts on both the path language and the dispatching semantics.

p.s. No, I’m not actually calling this “Urlang”.

BingD'OH!

DHH keynote buzzword bingo

Specifying Duck Types in Ruby

While prototyping a RESTful web service, I wrote the following code to allow Rails to parse a request’s parameters from a POST request containing JSON.


ActionController::Base.param_parsers[Mime::JSON] = JSON.method(:parse)

Unfortunately, it did not work, while the following code did:


ActionController::Base.param_parsers[Mime::JSON] = lambda { |data| JSON.parse(data) }

Theoretically, both of these should accomplish the same thing: assign an object that responds to the message call with an arity of 1 to Mime::JSON entry of the param_parsers hash. They lead to different results, however, because a case statement within the Rails HTTP request parsing code watches for an instance of Proc, instead of an object which responds to call.

As a proof of concept, I whipped up this DuckType class:


class DuckType
  def initialize(*args)
    @args = args
  end

  def ===(other)
    @args.all? { |arg| other.respond_to?(arg) }
  end
end
Now, we can replace this statement from cgi_methods.rb

case strategy = ActionController::Base.param_parsers[mime_type]
  when Proc
    strategy.call(raw_post_data)
  # snip...
end
with the following:

Callable = DuckType.new :call
case strategy = ActionController::Base.param_parsers[mime_type]
  when Callable
    strategy.call(raw_post_data)
  # snip...
end

As you can see, an instance of DuckType has a case comparison operator which asserts that all specified messages are supported, allowing you to focus on an object’s capabilities rather than its class.

My DuckType implementation in its current form is rather crude, but if enough people found this technique useful, I would consider properly packaging and extending it for general use.

A compelling alternative to Hpricot

After re-reading Nat Pryce’s Scrapheap Challege writeup, I tried to see how easily I could answer a simple question with only lynx, grep and friends. It turns out to be even simpler than I suspected. For example, the following tells me that my average blog post receives 2.2 comments.


# iterate through 17 pages
page=1; until [ $page -eq 17 ] ; do
  lynx -dump "http://www.jvoorhis.com/articles/page/$page" | \
    egrep "([[:digit:]]+|no) comments?" | \
    sed -e "s/\[.*\]//g" -e "s/no/0/g" | \
    awk '{print $1}' >> comments.txt
  page=$(( page + 1 ))
done
avg comments.txt 

	

Module#method_added

Two days ago, I discovered Module#method_added lurking about in the DRP library. Today, let’s take a look at what it does, along with an example implementation of multiple dispatch for Ruby objects.

Module#method_added accepts one parameter – a symbol allowing us to reference the method that was just defined in a class or module definition. We may do a number of things with only that method name – inspect the method, rename it, change its scope, or – in our case – register it with our multiple dispatch system.

The following code is both crude and simple: it allows us to define multimethods based on their arity, and does not support optional arguments or variable-length argument lists. It also only takes hold within the multi do ... end block. With a little extra work, the multi block could be eliminated, and missing features could be added. What is noteworthy is how reflective callbacks such as Module#method_added and Class#inherited make it possible to use the Ruby language to extend the Ruby language.


module Multi
  module Arity
    def method_added(name)
      if @__multi_def__
        @__multi_def__ = false # Disable method_added behavior while aliasing
        arity = instance_method(name).arity
        @__multi_methods__ |= [name]
        class_eval "private :#{name}; alias __multi__#{name}__#{arity} #{name}" 
        @__multi_def__ = true
      end
    end

    def multi
      @__multi_methods__ = []
      @__multi_def__ = true
      yield
      @__multi_def__ = false

      @__multi_methods__.each do |name|
        define_method(name) { |*args| send("__multi__#{name}__#{args.size}", *args) }
      end
    end
  end
end

if __FILE__ == $0
  require 'test/unit'

  class Example
    extend Multi::Arity
    multi do
      def hello
        "Hello, somebody" 
      end

      def hello(name)
        "Hello, #{name}" 
      end
    end
  end

  class MultiTest < Test::Unit::TestCase
    def test_dispatch
      ex = Example.new
      assert_equal "Hello, somebody", ex.hello()
      assert_equal "Hello, multimethods", ex.hello("multimethods")
    end
  end
end

Genetic Madlibs

Inspired by the eigenclass language generator, I’ve thrown together an example of how it would be implemented with the Directed Ruby Programming library. Directed programming is an interesting hybrid of genetic programming and the recently discovered grammatical evolution technique which generates a program tree according to a grammar.

This example may not be very interesting for those familiar with evolutionary programming techniques, but it created a fun diversion, highlights how the DRP library is to be used, and shows a different solution for a language generator.


class DrpGenerator
  extend DRP::RuleEngine
  begin_rules
    def main() "#{hello}\n#{ex1}\n#{ex2}" end

    def hello() "Hello, #{somebody}!" end

    def somebody() "matz" end
    def somebody() "world" end

    def ex1() "This is a more #{adj1} #{example}." end

    def adj1() "complex" end
    def adj1() "elaborate" end

    def example() "example" end
    def example() "test" end

    def ex2() "Some simple sentence." end
    def ex2() "Another, involving harder stuff." end
    def ex2() "Another, involving a more complex #{exp}." end
    def ex2() "Yet another possibility; each one is chosen with an evolutionary algorithm." end

    def exp() "expression" end
    def exp() "disjunction" end
    def exp() example end
  end_rules
end

g = DrpGenerator.new
3.times { puts g.main }

Hello, matz!
This is a more elaborate example.
Another, involving a more complex disjunction.

Hello, world!
This is a more elaborate test.
Another, involving harder stuff.

Hello, world!
This is a more complex example.
Yet another possibility; each one is chosen with an evolutionary algorithm.

My DrpGenerator isn’t as readable or attractive as the eigenclass DSL, and multiple definitions of the same method will likely confuse most Rubyists at first glance, but makes it easy to see the underlying grammar.

Large merge, tiny automation

or, awk’s not dead

At Values of n, we branch our codebase to create a safe environment for experiments or non-trivial changes to Stikkit. After spending a week on the east coast for holidays, I had the cough pleasure of merging over a weeks’ changes into my branch to keep current.

In my first approach, I tried merging everything at once. I ended up catching a multitude of conflicts – some of which made no sense since I was missing a weeks’ worth of context in a fast-paced environment. Clearly that was not the way to go.

My second attempt: divide and conquer. Using our revision history to look up changesets, I merged a day’s worth of changes at a time. Because a small number of issues tend to prevail on any given day, this allowed me to deal wih actual conflicts as they came. Actual, meaningful conflicts as opposed to conflicts in binary files or code I haven’t touched.

For reverting and resolving files I had no interest in, I learned the smallest bit of awk.

svn st | awk '/^C/ { print "svn revert " $2 | "sh"; print "svn resolved " $2 | "sh" }'
This handy one-liner finds all conflicted files from the output of svn status, reverts them, and resolves them, allowing me to proceed. Other awk invocations resolved conflicts for a particular set of files by copying them from another directory and resolving. Familiarity with tools like lex and racc made awk a cinch to learn and more useful than I would have guessed.


Open question: what small-time automation do you rely on to support regular development?

Things I Figured Out

As you might guess, I’ve been tremendously busy between launching Stikkit, running my first Craft Workshop (a success!), writing a book, and keeping up with holiday plans. I’m breaking the silence, however, with a short list of THINGS I FIGURED OUT.

  1. I’m 100% more productive when I’ve had my morning coffee. Bad sign?
  2. When working from home, I can use the time spent commuting to catch up on my reading. I’m currently reading On Certainty by Ludwig Wittgenstien and a novel by Salman Rushdie.
  3. While we usually wear a t-shirt and jeans at the office, occasionally wearing a necktie feels good.
  4. One-on-one training and teaching a group are two vastly different activities. A good way to keep things flowing is to pair up students who can help each other.
  5. Stikkit is great for travel plans. Pasting in my JetBlue itinerary and inviting friends and family just works.

Why Study Architecture First?

In my workshop, Understanding Web Architecture Through Ruby on Rails, I will delve straight into web architecture before discussing Rails at all. Here are 5 reasons why:

You should study web architecture if you want to…
  1. get a fresh perspective on Rails, and a better understanding of how the components of the model-view-controller pattern can fit together in a web framework.
  2. strive for coherence and good style at all levels of your application.
  3. share meaning with your users by exposing your domain model clearly to your users.
  4. learn how to take advantage of HTTP’s functionality and semantics, without spending days combing over RFCs.
  5. make applications that are available to agents other than web browsers, like feed readers or 3rd party apps, without duplicating code.

A Rails Documentation Trick

Most Rails projects that I work on these days are on some revision of edge Rails, depend on a few plugins and a development team of more than one. To keep up with the changes, I run the doc:rails and doc:plugins tasks semi-frequently, and I always make an effort to document the application code I write for posterity’s sake.

To make the documentation more usable – for myself, anyways – I created a task called doc:all that compiles the documentation for Rails, plugins and application code in one place. By doing so, I can usually find what I’m looking for quickly by using Ctrl-f find in my browser. Perhaps you’ll find this Rake task useful too.

As an added bonus, the task will use Jamis Buck’s RDoc template as seen at rails.rubyonrails.org if it is available at RAILS_ROOT/doc/jamis.rb. Enjoy.

Files

I'm Building Something Remarkable

As of yesterday, I am officially a member of Values of N.

Michael, Jeremy, Rael and Surj

I’ve been tasked with building up the infrastructure of Stikkit, the “little yellow notes that think”. Stikkit is a remarkable personal information-wrangling product, but you don’t need to take my word for it. On 7 November, Stikkit will takeoff from the Web 2.0 Conference Launch Pad.

Values of N was founded by Rael Dornfest and is based here in Portland, OR. I’m fortunate to be on a wonderful team with some highly talented and motivated individuals. Their enthusiasm is contagious.

Anticipating some questions that may arise, here is my professional status.

Consulting Unavailable for new projects
Rails in a Nutshell Due before RailsConf 2007
Craft Workshops Will not deviate form plan, first workshop will be held on 9-10 November
Articles Two book reviews are forthcoming

Craft Rails Workshop: Last Chance for Early Registration

Today is 16 October, and the last day for early registration for Craft: Understanding the Web Through Ruby on Rails. Early registration is set at a low $350, but will climb to $450 tomorrow.

If you or your team want to deepen your understanding of Ruby on Rails, domain modeling and web architecture, and benefit from some guided hands-on experience, I advise you to register today!

Why Attend a Craft Workshop?

I am hosting a Ruby on Rails workshop titled Understanding Web Architecture Through Ruby on Rails here in Portland, Oregon on 9-10 November. If you are deciding whether or not to attend, but are unsure what it’s all about, allow me to explain.

Many developers encounter Ruby on Rails for the first time via the numerous screencasts and tutorials that are available. Without doubt, this media demonstrates the productivity of Ruby on Rails, but within a limited realm. Application design is not always trivial, and it is easy to paint yourself into a corner with a new technology. Understanding Web Architecture… jumpstarts your Rails development career by giving me an outlet to share knowledge I have accumulated the hard way.

Understanding Web Architecture… also goes beyond the basics to focus on RESTful application design, what benefits it brings, and how it can be implemented in your Ruby on Rails applications from the start. I will be discussing domain modeling techniques, and how domain modeling can be applied to the higher level of web resources. To demonstrate the power in this approach, we will build a simple time-tracking application with both a browser interface and extend it to expose a web services api.

Finally, what sets this workshop apart is not an emphasis on familiarity of the Rails api, but a deeper understanding of how it works, what ideas have shaped it and where it may be going.

See you there!

PDX.rb Keeps On Rolling

Portland, Oregon is fortunate to have a beautiful Ruby users group, and last night’s meeting confirmed that to me even more. For those of you who couldn’t be there, or would simply like to peek inside, here is a quick summary.

Mercurial

John Labowitz clued us in about Mercurial, a decentralized scm tool in the same class as Darcs and BZR. The tool is still rather young, but seems to be improving rapidly. After covering some of its features and their usage, John deployed a Rails app from a Mercurial repository with a relatively simple Capistrano recipe. After listening, here is my take on Mercurial:

  • Decentralized – every working copy is a branch
  • Patches may be cherrypicked a la Darcs
  • Commands and output mirror Subversion when reasonable – svn users should be at home with the command line tool
  • Changesets are given a local revision number, for those of us who still think in Subversion

I’ve not used decentralized scm for programming-in-the-large, but have been using Darcs for one-off personal projects. Next time, I’ll kick the tires on Mercurial myself.

OS X Sync Services

Ben Bleything gave a talk about implementing Ruby applications that use Apple’s Sync Services. (I am not an OS X hacker myself, and I was mostly satisfied when Ben said Sync Services is like the windows registry, but for data.)

A Sync Services application typically has its own data store, but subscribes to updates from Sync Services and occasionally publishes its own. The examples that Ben showed involved observing the changes pushed by Sync Services via Growl notifications, and manipulating OS X address book entries via Ruby.

The examples also gave us a taste of Ruby/Cocoa; if there is a wrapper for the library you need, things are good. If not, you need to fire up the Objective-C documentation and translate the interface to something the Ruby/Objective-C bridge can understand. (Ben, help me out if I’ve messed anything up :)

Craftsmanship

After the talks, the group faithfully migrates to the Lucky Lab brewpub. Informally, I got a chance to talk to some fellow group members about the Rails workshop I will be holding in November. The name I have chosen for the series is Craft, referencing the passionate developer’s sense of craftsmanship as well as his desire to create.

Eric Wilhelm, joint member of PDX.rb and the Portland Perl Mongers, brought it to my attention that the last PDX Perl Mongers meeting held a panel on craftsmanship. The panel included Bricolage developer and esteemed acquaintance David Wheeler, bicycle machinist Dan Falck, and science fiction author David D. Levine. The podcast is available via the meeting page.

Props for taking the interdisciplinary approach!

Tags: pdx.rb, ruby

Two More Eye-Opening Programming Language Experiences

As a followup to my last post, here are some brief musings on other recent language experiences I have had that have challenged my comprehension of programming languages. If you have any experiences to share of your own, by all means do!

Common Lisp

Lisp is among the earliest families of high-level programming languages, and it has many incarnations, from the semantically pure Scheme to the pragmatic Common Lisp. Lisp looks daunting, at first, because of its mandatory use of parenthesis for expressing nesting - if you squint, it all looks the same.

One feature that sets Lisp apart from other languages is its ability to treat code as data. Since Lisp functions and Lisp data structures are represented the same way, Lisp's macro system allows you to manipulate Lisp programs at compile time as if they were simple data structures. This allows Lispers to write custom dialects to concisely express common abstractions.

While Lisp is often written about as being esoteric and difficult to grasp for non-Lispers, Practical Common Lisp takes you through a whirlwind tour of vital Lisp techniques and makes them easy to understand; the reader should have a good grasp of macros and where they fit into the development cycle by the end of the book, as well as packaging lisp code as modules and other techniques for programming-in-the-large. Find it at your bookstore or read it online.

Text: http://www.gigamonkeys.com/book/

Language: Common Lisp - try SBCL

Important Concepts

  • Code as data
  • Rapid prototyping
  • Meta-programming
  • List processing - destructuring, et. al.

C++ Template Meta-Programming

If you're like me, you may have learned the basics of C++ at your university and left it at that. What my college didn't tell me about was how the language was re-invented within the last decade by important works such as Andrei Alexandrescu's Modern C++ Design and the Boost community.

The latest C++ techniques have led to highly flexible generic implementation of design patterns and interesting libraries for functional programming and parser generation. I was particularly surprised when I discovered relatively sane implementations for multiple dispatch over value types (think archetypal multi implementations of factorial and fibonacci functions). I implore you to go ahead and explore - you might be surprised at what you find.

Resources

Language: C++ - if you're reading my blog, it's highly likely that g++ is already installed on your system.

Important Concepts

  • Generic programming
  • Template meta-programming

Three Eye-Opening Programming Language Experiences

As a professional programmer I am devoted to my ongoing education, and sometimes this leads me to learn new languages. My criteria for learning languages does not hinge on their practicality for my everyday use – in fact, it is likely that I will only use one of the following languages for profit – but new languages can arm me with new problem solving skills and deepen my understanding of programming in general.

Each of the experiences I am setting forth here are accessible. That does not mean they are easy, but language implementations and tutorials I will reference are all freely available online.

Ruby – The (Poignant) Guide

I won’t repeat here how I learned Ruby, but I will give some credit to Why’s (Poignant) Guide to Ruby. The guide is presented in a surreal comic book world with talking foxes and man-eating goats, but highlights many crucial aspects of Ruby including blocks and meta-programming. If you are learning Ruby, have a playful attitude and want to learn Ruby quickly, spend a few hours with the Guide – and don’t say I didn’t warn you!

Text: Why’s (Poignant) Guide to Ruby

Language: Ruby

Important Concepts:
  • Fundamentals of Ruby
  • Blocks
  • Meta-programming

Erlang

I was vaguely aware of Erlang as a functional language for some time, but my curiosity was aroused after a discussion with Jason Watkins about object-orientation in Erlang. Erlang’s distinguishing feature is its process model (Erlang processes, not operating system processes). Once established, Erlang processes can then communicate with each other via message passing, and closely resemble the Actors Model. Each process can maintain some state through recursion and communicate with outside processes by passing them messages, making them very similar to objects in common OO languages.

The Erlang tutorial is well-written, although it helps to have some prior knowledge of functional programming. If you are interested in challenging your understanding of object-oriented programming, take a look at Erlang.

Note: Ian Bicking wrote a good article about Erlang processes.

Text: Getting Started With Erlang

Language: Erlang

Important Concepts:
  • Concurrency, actors model
  • Object-orientation
  • Functional programming

Prolog

I’ve known about Prolog for a long time and understood some of its principles, but trying it out was completely different. After googling one day, I found a good tutorial that introduced me to the language. I learned about constraint programming, programming with goals rather than statements and expressions, and running the program “backwards” to find the parameter-space for a given solution. The tutorial also challenged my knowledge of destructuring and recursion.

The example programs in the tutorial are good, and include such problems as coloring regions on a planar map and identifying animals by their attributes. It also explains how Prolog does what it does and includes more advanced topics, such as prototyping and processing a grammar that resembles the English-language.

Note: for an interesting constraint programming example in Ruby see Jim Weirich’s solution to Ruby Quiz #70.

Text: prolog :- tutorial

Language: Prolog – SWI-Prolog worked well for me.

Important Concepts:
  • Logic programming
  • Constraint programing
  • Destructuring and recursion
Tags: languages

Tying Down Feature Ecology

Feature ecology is a collection of concepts I am developing in an attempt to frame my work as a technology producer. The term feature ecology pays homage to media ecology from which I draw some inspiration. While feature ecology intersects with media ecology, it focuses on product utility and aesthetics.

In my last post, I introduced the term feature ecology. The discussion that took place in the comments, however, digressed from the meaning I intended to share. In an effort to clarify the already-overloaded terms I have chosen, here are some operating definitions.

Feature
A unit of behavior and perceptual attributes. For practical reasons, a feature may be defined recursively, as a set of other features1.
Product
An environment consisting of features which a user may interact with.

Features provide an arena for human behavior. Features also have an agenda – their capabilities inform the user of what is important, and through ommision, what is not important2. A product will contain features that reflect the values of its producers, and – hopefully – the values of its users as well. Interactions also take place between features, as I have mentioned in my last post. Depending on the product, the addition of a feature may change the way users interact with features. A new feature may also make prior features more or less valuable to their users.

In response to the original post, Brian Ford wrote,

I’m cool with the zen-ish “products are features” but “features collected are not products” if I’m just being contemplative. But I’m wondering how does this help me think about software?

How can feature ecology assist us in creating better products? It reminds us to be aware of the behaviors we wish to evoke in our users. It also requires an awareness of the interactions between features within a given context; when adding a feature, we must consider to what extent we are redefining the product, and how consistent its messages are with neighboring features.

1 This definition is purposely vague on some levels. I work in the domain of web applications, but I think similarly about desktop software, my iPod, the newspaper, and anything else I call “technology”.

2 Marshall McLuhan stated this more succinctly when he said, “The medium is the message”.

Feature Ecology

Throughout my years as a software developer, I have come to recognize that it is silly to think a product can be improved by adding features. A product is its features. More specifically, it is the union of its features within a given context. When a feature is added to a product, the nature of that product has changed. Can you imagine a product with no features? I doubt it. Can you describe a product without mentioning any of its features? Can you compare two products while ignoring their features? Try it.

Features are not additive; they alter the environment of all other features. I recall when 37signals added Writeboards to Basecamp. When posting to Basecamp, I decided whether I was posting a living document which would be best handled by Writeboard, or a temporal message, which was best handled by the messages feature of Basecamp. Messages also excelled at fostering discussion, but Writeboards did not; they were more wiki-like, and over time the identity of the original author matters less and less. Later, 37s integrated Campfire with Basecamp. Since then, Basecamp users who want to initiate a discussion can use the cooler messages option or the warmer Campfire group chat.

After these two features were added to Basecamp, its messages weren’t used in quite the same way. If you are reading this blog, it is very likely you are participating in creating a product of some sort. Do you have compartmentalized ideas of a product and its feature list? Do you implement features in isolation, or can you find the interactions between features within your product’s environment?