» Publishers, Monetize your RSS feeds with FeedShow: More infos (Show/Hide Ads)
Only because this guy and then that guy asked.
What was your technical background before you started learning Ruby/Rails?
I remember playing with Basic as a kid. My brother had these great choose your own adventure style books where you had to type in basic listings to get to the next part of the story. I typed them in to my parent’s Apple IIgs (we had the Woz signature, yeah bay-be!). I thought it was quite cool, but didn’t really go anywhere with it.
My brother was great. Even though I only had a passing interest in software as a kid, he exposed me to a lot of great ideas just by talking, in particular functional programming.
In my more teenage years I played with OO Pascal in delphi. I did some TCL to script IRC. I liked to learn about programing, but didn’t really do much with it. I read a book on c, and picked up the basics of the c abstract machine.
I developed an interest in game development. I read Foley and van Dam and loved it. I skimmed the web of research literature, starting from Siggraph proceedings, Hughes Hoppe, Seth Teller, Larry Gritz and others. I enjoyed thinking about algorithms quite a bit, but didn’t do much to apply them.
I did some contract art and design for games, and got exposed to some minor in game scripting.
I worked for a CRM VAR for a bit and got exposed to web development with asp. I also played with the early betas of .NET.
I did a little PHP on the side, and hated it.
I worked a non-technical job for a couple years. Around this time I discovered citeseer. I skimmed thousands of papers, and printed hundreds to read in more depth. I don’t exaggerate. I filled my two filing drawers and covered my desk with tall piles of printed papers, only to dump it all in the recycling bin. This repeated 4 times.
I wish I’d kept notes, because I haven’t retained that much detail, but I do find it satisfying to have a sense of the geography of CS.
I read Hennessy and Patterson, loved it, and read a couple compiler books too. I highly recommend this.
How long ago did you start?
I learned the basics of Ruby circa 2001 at the CRM VAR. I had a small scripting task: generating some human friendly temporary password tokens. Perl is what you use for that, right? I’ll learn that, let’s go take a look at it. Bleh. Hrm, maybe there’s some Perl alternatives. Oh hey, this Ruby looks cool. Wait, that’s what I can use to do… and 15 minutes later it worked.
I was hooked.
I kept a passing interest in Ruby after I tired of technical work, and occasionally attended the local users group.
What were the two most useful resources to you in the learning process (not counting the Agile Book or the Pickaxe Book, which we’ll assume everyone knows)?
1. Community.
The blogs, the local users group, irc… they’ve all been invaluable in helping me learn. In particular I want to single out Jeremy Voorhis for teaching me a staggering amount while I was at PA, and being willing to debate topics I found interesting.
2. The Source.
Consistently, the source is the best place for me to answer the tricker questions about rails. Looking at other people’s source is how I’ve learned the most useful ruby. If you’re new to Ruby, this may be a bit daunting. I certainly find portions of the Rails source intimidating. But dig in there, it’s totally worth it.
Tell us the story of how you came to learn Rails:
In late 2004, someone in the portland ruby group mentioned Rails. I’d tried to play with mod_ruby, and found the experience mostly dissatisfying. I checked out Rails. I liked it. I kept an eye on the early blogs, the heiraki and the trac (until it got insanely busy).
In spring 2005 Lucas Carlson gave an intro to Rails talk for the Portland Ruby Group and the portland perl mongers. It was a good talk, and way more people than the ruby group had ever attracted before that time. More than when Matz came for OSCON a few years prior (sorry Matz). I got the feeling that I was one of only a couple people in the room who’d gotten into rails farther than the screencast, but still, the response was thought provoking.
In late 2005, rails really started to hit. I realized I could do this for a living. I hadn’t been interested in a technical job for a while. The chance to work with small, smart, early adopter companies, and to do with with Ruby was way to good to pass up. I started freelancing. In December, 2005, I started working with PLANET ARGON. I learned an amazing amount in my time there.
Three Ruby bloggers to whom you’re passing the baton:
Coda Hale made a blog post that started some controversy and interesting debate some time back that I had missed. I started a comment which became lengthy enough to post here instead:
I think the root difference of this debate is that you have a very narrow interpretation of CRUD, coda, and by proxy, REST.
Most people would agree rdbms’s can be described as CRUD systems, yet their behavior is quite rich. Even just the R encompasses projection, generalized selection by arbitrary propositions, products (joins), etc. The key insight of Cobb’s relational database is that the basis of operators provided by relational algebra are sufficient for a huge domain of applications. Meanwhile the uniform interface allows a wide variety of client applications.
Likewise, in the REST thesis the concept of resource is quite rich, including resources that have behavior (ie the code on demand constraint). The CRUD part only applies to the uniform interface which is used between client and server to exchange representations. The domain of ‘RESTful’ applications is similarly large, as is the flexibility in clients.
On to specific responses:
How do you crop an image with CRUD?
Couple options:
- Download an editor resource that can generate a preview and post/put the selected parameters.
- Update an image model object via a request and return a server side generated image.
The interesting thing about case 1 is that the uniform interface constraint of REST implies that you could implement option 2, then implement option 1 to have client side preview calculation, but PUT/POST to the same URI as option 1 to store the finally selected crop parameters. I’m sure you can start thinking about how that might enable simple html, js and flash based editors to talk to the same server endpoint, and how this general principle is useful for eliminating code duplication.
ActiveResouce is likely to take this a step further and allow us to use the same sort uniform interface within our server side code, factoring out a single monolithic application into a cluster of cooperating services.
How do you browse a hierarchical set of categories?
Resources are typically structured in collections. Nothing says collections can’t be nested. Or more formally, our URI can represent a directed walk starting from any acceptable root of the data graph.
How do you retrieve all non-published articles? All articles which have the approval of the desk editor, but not the section editor, which haven’t been flagged for review, with all their associated images, all the while checking that these actions are permissable according to the appropriate ACL with CRUD?
This is why we have query strings on collection resources (or matrix urls). Your very narrow view of CRUD seems to miss the concept of index, or that it might be predicated in some manner. Again this is similar to stating that databases aren’t CRUD because you can retrieve relations that match arbitrary criteria. Obviously databases can handle the above. Are we to decide databases aren’t CRUD?
At some point you’ll be looking at your controller’s actions, each of which is 80 lines long and contains nested case statements inside conditionals, each with an average of 10 different return paths, and you’ll wonder where the hell all that simplicity went.
This was DHH’s key point. When this happens, the message is not “CRUD failed me”, but “My models need to be re-factored”.
There certainly are exceptions, but I think this perspective is quite useful in practice.
From Jim Greer’s interesting blog post, Don’t say CRUD, say FUC’D :
Of course you don’t just want to delete a trouble ticket. You want to know more. And that’s a sign that the operation shouldn’t have been on the TroubleTicket in the first place. You want to have a “TicketClosure”. Then you’ll realize that you want to store a resolution as well as the person who closed it and the date. Now you’ve got a very useful part of your domain model – the hint was that you were writing some thing that wasn’t CRUD – you needed a new noun instead of a non-standard verb.
Something really clicked for me here. Domain models are about storing and manipulating information that represents the world. Typically we do this with objects. There’s a tired metaphor that objects are the nouns, and their methods are the verbs. But maybe that perspective is missing something interesting. What if we start thinking purely in terms of nouns?
What if our domain modeling is just about accumulating history over time? What if it’s all just about the existence of facts and relationships? What if all we do is add nouns using standardized verbs, rather than having a vocabulary of verbs?
There’s something about this I like a great deal. Instead of having methods that let us ask about and manipulate an object’s hidden state, we enrich the relationship modeling to encode the history of events as facts directly.
What do we gain?
We have knowledge not just of “what is”, right now, but also a detailed history of “what was”, back then. We can query across this history in a standardized way, and compose novel ad hoc views of the information with standard operators.
What do we lose?
Perhaps simplicity. Sometimes it’s just simpler to say ticket.close! than to create a new TicketClosure object with the appropriate relations.
How do we balance this tradeoff?
I find it an interesting perspective that I hope to leverage in future work: looking for opportunities to turn a verb into creating an instance of a noun.
I’m leaving the core team at PLANET ARGON.
It’s with a bittersweet feeling that I go. Working there has been intensely rewarding, and I’ve enjoyed the last half year, but it’s time we took different paths. I wish them well, and look forward to seeing what they’ll achieve.
Where does my path go?
I’ll be exploring in more detail some small ventures I’ve wanted to pursue for some time, and some additional opportunities I need to do due diligence on.
I’ll also have some availability for contract work, giving priority to projects that will provide an opportunity to show a strong initial ROI to my client or expand Rail’s capabilities.
Think your project may fit? Drop me a line and let’s talk.
Also, this blog will most likely be changing as I dedicate more time to contributing back to the Rails community which has been so generous to me.
Code is a static promise made against changing requirements in a dynamic world.
Every line is a liability. This implies you should both minimize how much code you write, but also be supremely thoughtful in what you do write.
My point today is that, if we wish to count lines of code, we should not regard them as “lines produced” but as “lines spent”: the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger.
I went book shopping today and noticed something. Sometimes a picture says it all:

I’ve been intrigued with rspec since seeing the steady trickle of blog posts from folks like obie
Looking at this example some thoughts occurred to me.
- How can I easily see what context a given behavior applies to?
- If I want to understand a specific behavior, how do I know which places to look in the spec without scanning the whole file?
- How could we make this more DRY so that there’s less temptation to copy-past behaviors between contexts?
- rake like dependent contexts
- behaviors apply to context groups
require 'a_more_declarative_rspec'
context "empty" do
@stack = Stack.new :limit => 10
end
context "one item" => "empty" do
@stack.push 10
end
context "almost full" => "empty" do
(2..10).each{ |i| @stack.push i }
end
context "full" => "empty" do
(1..10).each{ |i| @stack.push i }
end
context_group "not empty" => [ "one item", "almost full", "full" ]
context_group "not full" => [ "empty", "one item", "almost full" ]
behavior "should accept an item when sent push" => "not full" do
lambda{ @stack.push Object.new }.should.not.raise
end
behavior "should complain when sent top" => "empty" do
lambda{ @stack.top }.should.raise StackUnderflowError
end
behavior "should complain when sent pop" => "empty" do
lambda{ @stack.pop }.should.raise StackUnderflowError
end
behavior "should return top when sent top" => "not empty" do
@stack.top.should.be 10
end
behavior "should not remove top when sent top" => "not empty" do
@stack.top.should.be 10
@stack.top.should.be 10
end
behavior "should return top when sent pop" => "not empty" do
@stack.pop.should.be 10
end
behavior "should remove top when sent pop" => "not empty" do
@stack.pop.should.be 10
contexts "almost full", "full" do
@stack.top.should.be 9
end
contexts "one item" do
lambda{ @stack.top }.should.raise StackUnderflowError
end
end
behavior "should remove top when sent pop" => "one item" do
@stack.pop.should.be 10
end
behavior "should complain on push" => "full" do
lambda{ @stack.push Object.new }.should.raise StackOverflowError
end- one place to look for a given behavior
- more dry
- should reduce bloat when we’re forced to deal with things that have very wrinkly behavior
- it’s far more cluttered and complex than the original
- it can require some creativity to structure contexts such that an expectation can apply verbatim across them all (example: make sure 10 is top of all the non empty stacks)
What do you think? A step in a promising direction, or simply a step to far?
I don’t make a big deal out of holidays, so I was a bit surprised when I showed up to the office today.
All I can say is that a year ago, I would have never predicted I’d be getting paid to do Ruby with such a cool group of people.
We’re growing fast at PLANET ARGON and I’m really happy that everyone here rocks.
So I really like the Pragmatic Programmers beta book program. I think it’s a great idea, and likewise with their Fridays.
These are bright ideas, and they really fill a need. So is any wonder other businesses are working on similar offerings?
Dave’s rant seems conflicted: he’s disappointed other publishers are imitating them, but yet confident that their other bright ideas about their internal processes will give them a secure competitive advantage.
I say relax Dave. Any bright idea worth doing will be imitated. Keep doing it better and I’ll keep buying your books.
Besides, books aren’t a zero sum game. The more folks that imitate these bright ideas and go on to produce quality, the happier I’ll be.
Imitation means choice and competition. And in my book, that’s good.
A List Apart posted a worthy rant the other day on the buzzword orgy that is web 2.0.
I think his final paragraph is spot on: unless you’ve somehow secured exclusivity via contract, patent, or the like, any idea worth doing will be done by many, many people. People smarter than you. People better funded than you.
If your only competative advantage is having the bright idea first, you might as well not. If your idea depends on being the big player in a zero-sum game, you might as well not.
Bright ideas are nearly worthless. Execution is everything.
You have to compete by building a better product and a better business around it. Work hard, market hard, and deliver something that is more useful to your customers. Concentrate on markets that have room for more than one solution. Don’t hope cleverness will save you.
Are you hoping, or executing?







