Getting Back to Smalltalk

This week I wound up trying to put together a sample “real-world” problem suitable for use in an automated web thing aimed at potential new hires. Of course, any actual “real-world” problem would be have too many extraneous details to make it suitable given the constraints of the web thing, but trying to create the illusion of real-world-ness was kind of fun.

Since this seemed like sort of a weird way to spend a day or two, I decided to make it weirder by implementing both my solution to the problem and the code to generate test data in a language I don’t use every day. Just for the heck of it, I picked Smalltalk (Specifically, Pharo), the first time I’ve written Smalltalk code in anger for… hmm. Let’s see… I wrote the intro chapter to this in about 2000, and even then it had been a couple of years since I really wrote something in Smalltalk. (For the record, my other choice was Clojure, but I seem to have some weird mental block about getting started on a Clojure project. Someday soon, though.)

Anyway, Smalltalk was interesting because the environment is so different from anything else going and because I really haven’t used it in so long, I was curious to see whether my reactions to the Smalltalk environment would be any different given how long it’s been. For example, the last time I worked in Smalltalk, SUnit and TDD wasn’t a thing.

Overall, successful experience. I was able to actually write the program. It probably took me a little longer than it would have in Ruby, just because I was a bit rusty and the Pharo UI was a little unfamiliar. But it works, and most of the code isn’t bad – it got a little ragged toward the end. Here are a few random notes about the experience:

Language Structure

Whatever the line between a “scripting” language and a “normal” language is, Smalltalk is on the “not a scripting language” side of it. Smalltalk is very much a purist language with a small, consistent syntax, and not a lot of the sugar that you get used to in the Ruby/Python/Perl neighborhoods. Method names tend to be longish, and although the environment encourages short methods, basically there’s more typing in Smalltalk than in the equivalent Ruby.

Smalltalk was created almost completely outside the C/C++/Java family of programming languages, which combined with its pure structure makes it feel somewhat alien. And I say that as somebody who likes Smalltalk and genuinely enjoyed working in the environment.

For example:
* The first element of an array is index 1, not index 0. Which, honestly, makes more sense.
* Smalltalk doesn’t have operator precedence, and is evaluated strictly left-to-right, so a mathematical expression like 2 + 3 * 4 will not give you the result you would get in, say, every other programming language ever.
* Smalltalk doesn’t use the dot-notation for method calls, instead, the dot is a statement separator. It has keyword arguments, as later borrowed by Objective-C. Strings are single quotes, double quoted strings are comments.

Then you get other things like all the boolean and loop logic being managed by the library rather than the syntax. Really, the only thing the syntax manages in Smalltalk is order of operations and a very small amount of literal syntax. There’s a rich set of collection classes, and the names and classes are just slightly off from what you are used to. Takes some immersion to get the feel.

Workflow

The other really unfamiliar thing about Smalltalk is the environment and workflow. Smalltalk source isn’t normally kept in files. Instead, you run a binary image of all the code in the Smalltalk environment. If I’m remembering correctly, a Smalltalker working on multiple projects would have a separate image for each project. (There are mechanisms for teams working together, but I don’t think they are very standard, and I’m not all that familiar with them.)

The thing about Smalltalk is that you are always inside the environment. The idea, for example, that Ruby is super-flexible in what it allows you to do at run-time is a trivial point in Smalltalk. Everything is at run-time, because the phone call is coming from inside the house, so to speak. Of course you can create classes and methods at run-time. If you couldn’t, the whole system would be unworkable.

The image contains your code, the entire Smalltalk system, and the state of all the objects therein. Smalltalk typically also has a mechanisms for export/import of source, and also for internal version control. I think it’s fair to say that dealing with the workspace is at best counterintuitive when you are used to dealing with text editors and files.

Your main interface with the Smalltalk system is the code browser, which allows you to view any class and method in the system. One method at a time. Quick Quiz – what’s the Smalltalk keyword to define a method? Trick question. Smalltalk doesn’t have one. Smalltalk just knows that the things you type into the code browser are methods, and the first line of a method is its name. Code browsers are very neat, but again, using them effectively is a skill – a big step is realizing you can have more than one of them open at a time.

What’s interesting to me are the places where the Smalltalk environment is still ahead of my regular code environments, and where it’s behind. On the plus side:

  • When you save a Smalltalk method, the code browser verifies that it’s syntactically correct before allowing the save. If you are calling a method or using a variable that doesn’t exist, you have to okay it – in some circumstances, you even have the ability to create the method or variable as part of the save process.
  • The browser has easy access to all old versions of a method that you are looking at.
  • It’s very easy to see places that might call the method you are writing.
  • The browser also has some powerful refactoring functionality built in.
  • Integration is amazing, since everything is running. To give one example, the code browser knows which methods are SUnit tests, and they display in the browser with a red/yellow/green/gray indicator of their current state (error/failure/success/not run). Individual tests can be run separately easily in the browser, and since they environment is already loaded, the tests run in an eye blink.
  • On a related note, the debugger is famously awesome. From a breakpoint, you can see the state of all variables, edit values, edit code, all nice and easy.
  • You also can create workspaces, which are just blank code windows that you can execute arbitrary snippets in, like a iRb loop, but a bit more flexible.

But there are some missing pieces:

  • The code editor itself isn’t as powerful as you are used to if you’ve been using Vim or TextMate or, hell, anything. I’m a big “typing is not the bottleneck” kind of guy, but still, I would have loved some macros or snippets or something.
  • The one-method on display per code browser limitation is, well, limiting. You can have multiple code browsers open, but that takes up a lot of real estate. Tabbed browsers, split windows, that kind of thing would be kind of nice.
  • Intellectually I know that it’s really hard to lose changes in a Smalltalk image, but it still feels fragile to me not to have files readable by an external tool. UPDATE: I could have been clearer about this. Smalltalk doesn’t save changes in the image as such, instead it saves all your changes and lets you play changes back. I was trivially able to recover about 30 minutes of work after a Pharo crash, simply because all the changes were recorded and easily placed back in the image. The Smalltalk setup is effective, but feels different from the way I tend to think about their projects.

One interesting feature of the browser based editing environment is that it’s very easy to create a new method that is based on an existing method. You don’t even have to cut and paste, just browse to the existing method, change its name and save. Smalltalk will create a new method based on the new name.

This is very nice from a getting code in the system standpoint, but it seems to have the side effect of encouraging more duplication in the system than I might be otherwise comfortable with. The effect is confounded by the fact that you can only see one method at a time in the browser, making it difficult to scan for duplication.

What’s not getting across here is how smooth the workflow in the small is when you really get the rhythm going. It’s an environment that really suits a “make a small change, evaluate the change” process. In some ways, it’s not surprising that the test-first movement would have gotten serious momentum in Smalltalk, test-first is just a formalization of the way a good Smalltalk programmer interacts with the system. Plus, I’m a purist in so many ways, and even though the code takes a little getting used to, I like the way it turns out.

So, successful test. Would try again. I still want to try something with Seaside one of these days just to see what that’s like.

Filed under: Smalltalk

Getting Back to Smalltalk

This week I wound up trying to put together a sample “real-world” problem suitable for use in an automated web thing aimed at potential new hires. Of course, any actual “real-world” problem would be have too many extraneous details to make it suitable given the constraints of the web thing, but trying to create the illusion of real-world-ness was kind of fun.

Since this seemed like sort of a weird way to spend a day or two, I decided to make it weirder by implementing both my solution to the problem and the code to generate test data in a language I don’t use every day. Just for the heck of it, I picked Smalltalk (Specifically, Pharo), the first time I’ve written Smalltalk code in anger for… hmm. Let’s see… I wrote the intro chapter to this in about 2000, and even then it had been a couple of years since I really wrote something in Smalltalk. (For the record, my other choice was Clojure, but I seem to have some weird mental block about getting started on a Clojure project. Someday soon, though.)

Anyway, Smalltalk was interesting because the environment is so different from anything else going and because I really haven’t used it in so long, I was curious to see whether my reactions to the Smalltalk environment would be any different given how long it’s been. For example, the last time I worked in Smalltalk, SUnit and TDD wasn’t a thing.

Overall, successful experience. I was able to actually write the program. It probably took me a little longer than it would have in Ruby, just because I was a bit rusty and the Pharo UI was a little unfamiliar. But it works, and most of the code isn’t bad – it got a little ragged toward the end. Here are a few random notes about the experience:

Language Structure

Whatever the line between a “scripting” language and a “normal” language is, Smalltalk is on the “not a scripting language” side of it. Smalltalk is very much a purist language with a small, consistent syntax, and not a lot of the sugar that you get used to in the Ruby/Python/Perl neighborhoods. Method names tend to be longish, and although the environment encourages short methods, basically there’s more typing in Smalltalk than in the equivalent Ruby.

Smalltalk was created almost completely outside the C/C++/Java family of programming languages, which combined with its pure structure makes it feel somewhat alien. And I say that as somebody who likes Smalltalk and genuinely enjoyed working in the environment.

For example:
* The first element of an array is index 1, not index 0. Which, honestly, makes more sense.
* Smalltalk doesn’t have operator precedence, and is evaluated strictly left-to-right, so a mathematical expression like 2 + 3 * 4 will not give you the result you would get in, say, every other programming language ever.
* Smalltalk doesn’t use the dot-notation for method calls, instead, the dot is a statement separator. It has keyword arguments, as later borrowed by Objective-C. Strings are single quotes, double quoted strings are comments.

Then you get other things like all the boolean and loop logic being managed by the library rather than the syntax. Really, the only thing the syntax manages in Smalltalk is order of operations and a very small amount of literal syntax. There’s a rich set of collection classes, and the names and classes are just slightly off from what you are used to. Takes some immersion to get the feel.

Workflow

The other really unfamiliar thing about Smalltalk is the environment and workflow. Smalltalk source isn’t normally kept in files. Instead, you run a binary image of all the code in the Smalltalk environment. If I’m remembering correctly, a Smalltalker working on multiple projects would have a separate image for each project. (There are mechanisms for teams working together, but I don’t think they are very standard, and I’m not all that familiar with them.)

The thing about Smalltalk is that you are always inside the environment. The idea, for example, that Ruby is super-flexible in what it allows you to do at run-time is a trivial point in Smalltalk. Everything is at run-time, because the phone call is coming from inside the house, so to speak. Of course you can create classes and methods at run-time. If you couldn’t, the whole system would be unworkable.

The image contains your code, the entire Smalltalk system, and the state of all the objects therein. Smalltalk typically also has a mechanisms for export/import of source, and also for internal version control. I think it’s fair to say that dealing with the workspace is at best counterintuitive when you are used to dealing with text editors and files.

Your main interface with the Smalltalk system is the code browser, which allows you to view any class and method in the system. One method at a time. Quick Quiz – what’s the Smalltalk keyword to define a method? Trick question. Smalltalk doesn’t have one. Smalltalk just knows that the things you type into the code browser are methods, and the first line of a method is its name. Code browsers are very neat, but again, using them effectively is a skill – a big step is realizing you can have more than one of them open at a time.

What’s interesting to me are the places where the Smalltalk environment is still ahead of my regular code environments, and where it’s behind. On the plus side:

  • When you save a Smalltalk method, the code browser verifies that it’s syntactically correct before allowing the save. If you are calling a method or using a variable that doesn’t exist, you have to okay it – in some circumstances, you even have the ability to create the method or variable as part of the save process.
  • The browser has easy access to all old versions of a method that you are looking at.
  • It’s very easy to see places that might call the method you are writing.
  • The browser also has some powerful refactoring functionality built in.
  • Integration is amazing, since everything is running. To give one example, the code browser knows which methods are SUnit tests, and they display in the browser with a red/yellow/green/gray indicator of their current state (error/failure/success/not run). Individual tests can be run separately easily in the browser, and since they environment is already loaded, the tests run in an eye blink.
  • On a related note, the debugger is famously awesome. From a breakpoint, you can see the state of all variables, edit values, edit code, all nice and easy.
  • You also can create workspaces, which are just blank code windows that you can execute arbitrary snippets in, like a iRb loop, but a bit more flexible.

But there are some missing pieces:

  • The code editor itself isn’t as powerful as you are used to if you’ve been using Vim or TextMate or, hell, anything. I’m a big “typing is not the bottleneck” kind of guy, but still, I would have loved some macros or snippets or something.
  • The one-method on display per code browser limitation is, well, limiting. You can have multiple code browsers open, but that takes up a lot of real estate. Tabbed browsers, split windows, that kind of thing would be kind of nice.
  • Intellectually I know that it’s really hard to lose changes in a Smalltalk image, but it still feels fragile to me not to have files readable by an external tool.

One interesting feature of the browser based editing environment is that it’s very easy to create a new method that is based on an existing method. You don’t even have to cut and paste, just browse to the existing method, change its name and save. Smalltalk will create a new method based on the new name.

This is very nice from a getting code in the system standpoint, but it seems to have the side effect of encouraging more duplication in the system than I might be otherwise comfortable with. The effect is confounded by the fact that you can only see one method at a time in the browser, making it difficult to scan for duplication.

What’s not getting across here is how smooth the workflow in the small is when you really get the rhythm going. It’s an environment that really suits a “make a small change, evaluate the change” process. In some ways, it’s not surprising that the test-first movement would have gotten serious momentum in Smalltalk, test-first is just a formalization of the way a good Smalltalk programmer interacts with the system. Plus, I’m a purist in so many ways, and even though the code takes a little getting used to, I like the way it turns out.

So, successful test. Would try again. I still want to try something with Seaside one of these days just to see what that’s like.

Filed under: Smalltalk

The art/craft/commodity continuum

When you create art, the purpose is self-expression.

When you create software, the purpose is rarely self-expression.

When you create software, someone somewhere wants it to perform a set of functions and has a stake in how well those functions are implemented. The definition of “well” is up to the stakeholder.

When you create art, you want it to be beautiful, or beautifully ugly, or ornate, or plain. You, the creator, are the stakeholder. You may hope that others find it beautiful, but if they don’t, it’s art—who’s to say what’s good and bad?

When you attempt to judge the quality of a commodity good solely in terms of its aesthetic appeal, you ignore the objective evaluation of how well that product meets the needs of its stakeholders.

When you attempt to judge the quality of a piece of art solely on some objective measure, you miss the point of the object as an expression of art.

Craft falls somewhere between commodity and art. Craft items have both subjective, aesthetic appeal and objective function.

This is a beautiful Christian Dior dress:

Beautiful but largely impractical. Try to wear this on the subway or even in your car. Try to fit it through a standard door. It’s a beautiful piece of art, but it fails as a useful article of clothing for most people.

This is a Paul Smith suit. It’s practical, extremely well made, creatively designed, and probably very expensive:

This is a pair of pants on sale at Wal-Mart:

Beautiful? I don’t know many people who would call this beautiful. Completely unremarkable.

And so it goes…from art to craft to commodity.

Now consider yourself as the customer here. My guess is that most of my readers, even with an appreciation of the quality of the Paul Smith suit, would be much more comfortable in the Wal-Mart pants.

When we create an item for another person, we have to consider whether that person is looking for art, craft, or commodity. We may wish to always be creating art. Or craft. But sometimes our customers want commodity. Not only is commodity cheaper but it’s what they prefer.

#310 Getting Started with Rails

Learning Ruby on Rails can be overwhelming, especially if you are new to programming. Here I will take you on a tour through various resources to help get started with Rails.

The 5 Most Popular Articles of 2011 on RubyLearning

(Based on Twitter Re-tweets)

The year 2011 saw RubyLearning’s awesome guest authors write and share their knowledge with others. If you missed any of these useful articles then here’s the roundup of the 5 most popular articles of 2011 on RubyLearning. Enjoy!

Throw, Catch, Raise, Rescue… I’m so confused!

Avdi Grimm explains the usage of Throw, Catch, Raise, Rescue in the Ruby programming language.

You’ve probably noticed that Ruby has throw and catch… but they don’t seem to be used the way you’re used to in other languages! And there are also these begin, raise and rescue statements that seem to do the same thing. What’s going on here?

Read the rest of the article: Throw, Catch, Raise, Rescue… I’m so confused!

Performance Testing Rails Applications – How To?

Gonçalo Silva shows you how to do performance testing of your Rails applications.

Rails’ performance testing tools allow you to quickly detect performance bottlenecks. As a rule of thumb, use benchmarking to detect the problem and then use profiling to understand it.

Read the rest of the article: Performance Testing Rails Applications – How To?

Do you ponder what to name things in your code?

Evan Light asks – do you ponder what to name things in your code?

Most of the time, someone has to maintain that pile of crap you just birthed! It may be someone else. It may be you! But it’s always wise to pretend that the person who will own your code next is an axe-wielding lunatic who knows where you live!

Read the rest of the article: Do you ponder what to name things in your code?.

How do I smell Ruby code?

Timon Vonk talks about Ruby code smells in an effort to improve Ruby code.

Writing bad code isn’t a bad thing. Not understanding the problem you’re trying to solve any better after having written that piece of code is. Fortunately, that happens far less often.

Read the rest of the article: How do I smell Ruby code?

How do I test my code with Minitest?

Steve Klabnik introduces the readers to Ruby’s minitest.

You run your program, try a few different inputs, check the outputs, and see that they’re right. Then, you make some changes in your code, and you’d like to see if they work or not, so you fire up Ruby and try those inputs again. That repetition should stick out. There has to be a better way.

Read the rest of the article: How do I test my code with Minitest?

Your turn: Share the link to a roundup post you’ve written. If you’ve never written a roundup, try it this week. Be sure to share the link to your post here!

Technorati Tags: , ,


(Powered by LaunchBit)

Pragmatic Guide to Sass now in print

Pragmatic Guide to Sass now in print; “Pragmatic” chosen as Word of the Year by Merriam-Webster.

Re-thinking Software Development Education

Where have I been lately? Good question. When asked over these past months, I jokingly say something like, “These last 8 months at LivingSocial have been the best 4 years of my career.”

But I don’t just mean I’ve been busy. I’ve been focused on building the best software development team I can to do what I think is some important and industry-changing work in the world of local commerce.

And when I joke about these 8 months being the best 4 years of my career, what I really mean is that I feel like I’ve learned 4 years worth of lessons and gained 4 years worth of experience. What we’re doing isn’t easy. It’s the kind of work I’ve always sought out.

I am a self-taught software developer. To date, my formal education consists of two 3-day training classes on specific programming languages (Java many years ago and Erlang in 2008). During my first work experiences in IT, I remember the shock of discovering that a Masters degree in software development doesn’t necessarily translate to knowing how to effectively use a computer. I was a saxophonist and system administrator and would regularly teach the computer scientists I worked with about things I would have assumed they learned in college.

As I headed further into the workforce I noticed another odd thing: people with tens of years of experience as software developers weren’t necessarily very good at it. My assumptions were based on what I had previously learned as a jazz musician. Jazz musicians polish and hone their skills throughout their careers. The longer a jazz musician has been playing, the more likely he or she is to be an excellent jazz musician.

Programmers, though. As far as I could tell the average programmer spent his day complaining about his co-workers and waiting for 5pm.

So what’s the disconnect? Some of it, of course, is just the people. Some programmers are passionate and some aren’t. Those that aren’t, aren’t going to be radically successful. Assuming this is the case in all fields, what’s really frustrating to me is that I continue to run into passionate developers who just don’t know the right stuff.

When I started out in this field, I was lucky enough to stumble onto a mentor. That too was probably informed by my experience as an aspiring jazz musician. Jazz musicians take the idea of musical lineage seriously and look for someone from whom to receive direction on how to parse the potentially overwhelming task of going from novice to master jazz improviser. My mentor in the software field did the same. He told me: first learn these three things. He picked topics that were diverse but complementary. He picked skills that set a foundation on which it was easy to build the next set. Most new developers don’t get so lucky.

And It’s not just technology skills. The developers I work with are entrepreneurs at heart. We aren’t sitting around polishing our tools and conducting thought experiments. We’re delivering stuff that matters and we hate working on projects that drag on or don’t deliver value. Becoming a great developer involves not just learning the ins and outs of software development but understanding how businesses work and exactly how software systems fit into that picture. It’s about delivering value quickly and iteratively. Great developers understand what Kent Beck and the rest of the authors of the agile manifesto were getting at a decade ago. And what people like Eric Ries are teaching today.

I’ve often thought “just give me 3 months with a smart person and I can have them running circles around the average developer.” Have you thought that too? I know a lot of my colleagues have.

It’s time to rethink how we educate software developers. Computers used to be huge scary machines in big white rooms that very few people touched. Today you probably have at least one computer ON YOUR BODY most of the time. They’re ubiquitous and friendly and just NOT that hard to work with. The technology landscape has changed. The system of educating developers should change along with it.

My colleagues are clearly thinking along the same lines. I’ve seen speakers such as Joe O’Brien talking about it this year. And we see programs popping up all over. Software Craftsman Ken Auer is launching the Craftsmanship Academy to teach apprentices the art and craft of software development in an intense hands-on residency-oriented program. Code Academy is a part-time 12 week course to accelerate the path to web development or design.

Today we’re launching a new program at LivingSocial called Hungry Academy. Hungry Academy is a five month intense entrepreneurial immersion that will take raw, hungry talented programmers (and aspiring programmers!) and develop them into ultra-productive software engineers. Those that make it through to the end will be offered a position on our development team and paired with a mentor from LivingSocial’s growing list of some of the industry’s most talented software engineers. Best of all, we will pay you to attend. Your job for five months is to take your craft and career to the next level.

This isn’t going to be easy. Some people will get in but won’t make it to the end. Those that do will spend five months gaining the best 4 years of experience of their careers.

Let’s Talk About Conditional Expressions

This guest post is by Evan Light a test-obsessed developer, the author of several rarely used gems, and the curator of Ruby DCamp. When he’s not a talking head at conferences, he’s usually working at home as a freelance developer remotely mentoring a developer, working for one or more startups, playing with open source, keeping his wife and four cats company, hacking nonsensically, talking at people on the internet, and/or attempting to lose weight (or any combination of the above). What else do you do when you live 3 hours from civilization?

Evan Light You know what bugs me? People who don’t write idiomatic conditionals in Ruby.

Many folks, especially those who came out of Java, .NET, or C/C++, use and abuse the ternary. The ternary is a humble little production rule that works like so:

<boolean expression> ? <eval this expression if truthy> : <eval if falsey>

The ternary can be useful if the truthy and falsey cases are terse and well-named. However, it’s common to see multi-line ternaries or, even worse, nested ternaries. For example:

By the way, the above example comes out of Rails.

Accepting that the above is just painful, how could we make it hurt less? Specifically, let’s focus on the nested ternary on Line 7 (accepting that there are other ways that the code can be made clearer).

For starters, let’s DRY up these Hash lookups:

Now let’s unravel this into more idiomatic Ruby. We’ll extract the outer ternary into a functional style if-else. Remember that every expression in Ruby returns the value of its last executed expression. The if-else returns either the value of the computed String in the if or the empty String else. It has the advantage of containing more English words and fewer characters that resemble modem line noise or PERL.

We can get rid of this else. After all, it doesn’t contain any logic. Let’s just make it the default value for method_prefix and then assign a new value only when prefix is truthy.

Ah so what this code really cares about, first and foremost, is whether prefix is falsey. When it’s falsey, it just returns an empty String! Otherwise, if it’s not, it generates a String possibly using the value of prefix if and only if prefix is not true – not a boolean.

So why should we try to avoid ternaries? Because, when used within a complex expression, they tend to lack the clarity of intent of an if-else. The lack of clarity likely resulted in the less DRY previous implementation. Once we introduced more clarity, it became obvious how this code could be DRY’d up, resulting in better readability.

I hope you found this article valuable. Feel free to ask questions and give feedback in the comments section of this post. Thanks!

Subscribe to the waiting list of the free, online “Intermediate Ruby Course“. As a bonus, get a free copy of the “Introduction to Rack” eBook (.pdf format).

Technorati Tags: , ,


(Powered by LaunchBit)

Rails/master is now 4.0.0.beta

The forthcoming 3.2.x release series will be the last branch of Rails that supports Ruby 1.8.7. There’s a new 3-2-stable branch in git to track the changes we need until 3.2.0 final is release and for managing point releases after that.

So for now you should stop floating on rails/master if your application is not compatible with Ruby 1.9.3. We have updated the version numbers to indicate this backwards incompatibility to be 4.0.0.beta. This doesn’t mean that 4.0 is anywhere close to being released, mind you. We’re simply doing this now because we’re dropping support for Ruby 1.8.7 in rails/master and people should know what’s up.

Major versions of Rails has been on about 2-year release cycle since 1.0 (released in 2005, followed by 2.0 in 2007, followed by 3.0 in 2010) and we intend to continue this pattern. The current internal target for Rails 4.0 is sometime in the Summer of 2012 — but we have blown every major release estimate in the past, so don’t bet your farm on it.

There’s not a lot of details about what we’re going to include in Rails 4.0 yet as the primary purpose for bumping the major version number is to drop Ruby 1.8.7 support. But unlike Rails 3.0, we intend for it to be a much smoother transition. The intention is not for this to be a REWRITE EVERYTHING release in the same way 3.0 was to some extent.

But we’re getting ahead of ourselves. First mission is to get Rails 3.2 out!

Rails 3.2 RC1: Faster dev mode & routing, explain queries, tagged logger, store

Once you’ve boarded the Rails train, you just know that every stop along the way is going to be a good time. This release candidate is no different and we’ve packed it with loving goodies without making upgrading a hassle.

Faster dev mode & routing

The most noticeable new feature is that development mode got a ton and a half faster. Inspired by Active Reload, we now only reload classes from files you’ve actually changed. The difference is dramatic on a larger application.

Route recognition also got a bunch faster thanks to the new Journey engine and we made linking much faster as well (especially apparent when you’re having 100+ links on a single page).

Explain queries

We’ve added a quick and easy way to explain quieries generated by ARel. In the console, you can run something like puts Person.active.limit(5).explain and you’ll get the query ARel produces explained (so you can easily see whether its using the right indexes). There’s even a default threshold in development mode where if a query takes more than half a second to run, it’s automatically explained inline—how about that!

Tagged logger

When you’re running a multi-user, multi-account application, it’s a great help to be able to filter the log by who did what. Enter the TaggedLogging wrapper. It works like this:

Logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
Logger.tagged("BCX") { Logger.info "Stuff" } # Logs "[BCX] Stuff" 
Logger.tagged("BCX") do
  Logger.tagged("Jason") do
    Logger.info "Stuff" # Logs "\[BCX\] \[Jason\] Stuff" 
  end
end

Active Record Store

Key/value stores are great, but it’s not always you want to go the whole honking way just for a little variable-key action. Enter the Active Record Store:

class User < ActiveRecord::Base
  store :settings, accessors: [ :color, :homepage ]
end
u = User.new(color: 'black', homepage: '37signals.com')
u.color                          # Accessor stored attribute
u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor

These are just a few of the highlights. The full release notes detail every loving change.

Given that this is a release candidate, we’re ever so eager to hear your feedback. We hope it’ll be a quick RC phase, but please do spoil that plan by reporting bugs.

As always, you install a release candidate by doing gem install rails --pre.

#308 Oh My ZSH

As Rails developers, we frequently use the command line. Here I will show how to switch to Z Shell using Oh My ZSH including how to make your own theme and plugins.

Learning from the masters

Jason and Peter talk about learning rails, profiling Rails startup times, and Josh Susser weighs in on files.

Got Quoted in the Wall Street Journal

Got Quoted in the Wall Street Journal. That doesn’t happen every day! :-)

Here it is:

“The funding of mobile first companies will increase significantly.” — Keith Teare, general partner, Archimedes Labs

Deploy Grails Applications on Heroku

We’re happy to announce the public beta of Grails application deployment on Heroku with support for Grails 1.3.7 and 2.0 provided by the open source Heroku Grails buildpack.

Grails is a high-productivity web application framework for the JVM based on the Groovy programming language and featuring many similarities with Rails. Since its inception in 2006, the framework has enjoyed broad adoption in the Java community as it combines the strengths of the JVM and richness of the Java platform with the productivity benefits of modern frameworks like Rails.

Today the Grails team announced Grails 2.0, the latest incarnation of the framework. It features numerous large improvements including an overhauled command line tool, faster and more reliable reloads, and static asset support. Details are covered in the What’s New section of the Grails docs.

The release includes the Grails Heroku plugin that provides simple commands to set up your Grails app with Heroku add-on services like Postgres, Memcached, Redis, MongoDB from MongoLabs or MongoHQ and RabbitMQ.

Deploying a Grails app on Heroku

Create a new Grails project:

$ grails createApp HelloWorld
| Created Grails Application at /Users/jjoergensen/dev/HelloWorld
$ cd HelloWorld

Commit to Git:

$ grails integrate-with --git
$ git init
Initialized empty Git repository in /Users/jjoergensen/dev/HelloWorld/.git/
$ git add .
$ git commit -m init
[master (root-commit) bd0f36b] init
 58 files changed, 2788 insertions(+), 0 deletions(-)
 create mode 100644 .classpath
 create mode 100644 .gitignore
 create mode 100644 .project
...

Create Heroku Cedar app:

$ heroku create --stack cedar
Creating smooth-night-8061... done, stack is cedar
http://smooth-night-8061.herokuapp.com/ | git@heroku.com:smooth-night-8061.git
Git remote heroku added

Deploy to Heroku:

$ git push heroku master
Counting objects: 73, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (69/69), done.
Writing objects: 100% (73/73), 97.82 KiB, done.
Total 73 (delta 2), reused 0 (delta 0)

-----> Heroku receiving push
-----> Grails app detected
-----> Grails 2.0.0 app detected
-----> Installing Grails 2.0.0..... done
-----> executing grails -plain-output -Divy.default.ivy.user.dir=/app/tmp/repo.git/.cache war

       |Loading Grails 2.0.0.
       ...
       |Done creating WAR target/HelloWorld-0.1.war
-----> No server directory found. Adding jetty-runner 7.5.4.v20111024 automatically.
-----> Discovering process types
       Procfile declares types  -> (none)
       Default types for Grails -> web
-----> Compiled slug size is 30.6MB
-----> Launching... done, v3
       http://smooth-night-8061.herokuapp.com deployed to Heroku

Learn More

Let’s Build a Simple Video Game with JRuby: A Tutorial

Ruby isn’t known for its game development chops despite having a handful of interesting libraries suited to it. Java, on the other hand, has a thriving and popular game development scene flooded with powerful libraries, tutorials and forums. Can we drag some of Java’s thunder kicking and screaming over to the world of Ruby? Yep! – thanks to JRuby. Let’s run through the steps to build a simple ‘bat and ball’ game now.

The Technologies We’ll Be Using

JRuby

If you’re part of the “meh, JRuby” brigade, suspend your disbelief for a minute. JRuby is easy to install, easy to use, and isn’t going to trample all over your system or suck up all your memory. It will be OK!

One of JRuby’s killer features is its ability to use Java libraries and generally dwell as a first class citizen on the JVM. JRuby lets us use performant Java powered game development libraries in a Rubyesque way, lean on Java-based tutorials, and basically have our cake and eat it too.

To install JRuby, I recommend RVM (Ruby Version Manager). I think the JRuby core team prefer you to use their own installer but rvm install jruby has always proven quick and effective for me. Once you get it installed, rvm use jruby and you’re done.

Slick and LWJGL

The Slick library is a thin layer of structural classes over the top of LWJGL (Lightweight Java Game Library), a mature and popular library that abstracts away most of the boring system level work.

Out of the box LWJGL gives us OpenGL for graphics, OpenAL for audio, controller inputs, and even OpenCL if we wanted to do heavy parallelism or throw work out to the GPU. Slick gives us constructs like game states, geometry, particle effects, and SVG integration, while allowing us to drop down to using LWJGL for anything we like.

Getting Started: Installing Slick and LWJGL

Rather than waste precious time on theory, let’s get down to the nitty gritty of getting a basic window and some graphics on screen:

  • First, create a folder in which to store your game and its associated files. From here I’ll assume it’s /mygame
  • Go to the Slick homepage and choose “Download Full Distribution” (direct link to .zip here).
  • Unzip the download and copy the lib folder into your /mygame as /mygame/lib – this folder includes both LWGWL and Slick.
  • In /mygame/lib, we need to unpack the natives-[your os].jar file and move its contents directly into /mygame.

    Mac OS X: Right click on the natives-mac.jar file and select to unarchive it (if you have a problem, grab the awesome free The Unarchiver from the App Store) then drag the files in /mygame/lib/native-mac/* directly into /mygame.

    Linux and Windows: Running jar -xf natives-linux.jar or jar -xf natives-win32.jar and copying the extracted files back to /mygame should do the trick.

  • Now your project folder should look a little like this:

    If so, we’re ready to code.

A Bare Bones Example

Leaping in with a bare bones example, create /mygame/verybasic.rb and include this code:

$:.push File.expand_path('../lib', __FILE__)

require 'java'
require 'lwjgl.jar'
require 'slick.jar'

java_import org.newdawn.slick.BasicGame
java_import org.newdawn.slick.GameContainer
java_import org.newdawn.slick.Graphics
java_import org.newdawn.slick.Input
java_import org.newdawn.slick.SlickException
java_import org.newdawn.slick.AppGameContainer

class Demo < BasicGame
  def render(container, graphics)
    graphics.draw_string('JRuby Demo (ESC to exit)', 8, container.height - 30)
  end

  # Due to how Java decides which method to call based on its
  # method prototype, it's good practice to fill out all necessary
  # methods even with empty definitions.
  def init(container)
  end

  def update(container, delta)
    # Grab input and exit if escape is pressed
    input = container.get_input
    container.exit if input.is_key_down(Input::KEY_ESCAPE)
  end
end

app = AppGameContainer.new(Demo.new('SlickDemo'))
app.set_display_mode(640, 480, false)
app.start

Ensure that ruby actually runs JRuby (using ruby -v) and then run it from the command line with ruby verybasic.rb. Assuming all goes well, you’ll see this:

If you don’t see something like the above, feel free to comment here, but your problems most likely orient around not having the right ‘native’ libraries in the current directory or from not running the game in its own directory in the first place (if you get probable missing dependency: no lwjgl in java.library.path – bingo).

Explanation of the demo code

  • $:.push File.expand_path('../lib', __FILE__) pushes the ‘lib’ folder onto the load path. (I’ve used push because my preferred << approach breaks WordPress ;-))
  • require 'java' enables a lot of JRuby’s Java integration functionality.
  • Note that we can use require to load the .jar files from the lib directory.
  • The java_import lines bring the named classes into play. It’s a little like include, but not quite.
  • We lean on Slick’s BasicGame class by subclassing it and adding our own functionality.
  • render is called frequently by the underlying game engine. All activities relevant to rendering the game window go here.
  • init is called when a game is started.
  • update is called frequently by the underlying game engine. Activities related to updating game data or processing input can go here.
  • The code at the end of the file creates a new AppGameContainer which in turn is given an instance of our game. We set the resolution to 640×480, ensure it’s not in full screen mode, and start the game.

Fleshing Out a Bat and Ball Game

The demo above is something but there are no graphics or a game mechanic, so it’s far from being a ‘video game.’ Let’s flesh it out to include some images and a simple pong-style bat and ball mechanic.

Note: I’m going to ignore most structural and object oriented concerns to flesh out this basic prototype. The aim is to get a game running and to understand how to use some of Slick and LWJGL’s features. We can do it again properly later 🙂

All of the assets and code files demonstrated here are also available in an archive if you get stuck. Doing it all by hand to start with will definitely help though.

A New Code File

Start a new game file called pong.rb and start off with this new bootstrap code (very much like the demo above but with some key tweaks):

$:.push File.expand_path('../lib', __FILE__)

require 'java'
require 'lwjgl.jar'
require 'slick.jar'

java_import org.newdawn.slick.BasicGame
java_import org.newdawn.slick.GameContainer
java_import org.newdawn.slick.Graphics
java_import org.newdawn.slick.Image
java_import org.newdawn.slick.Input
java_import org.newdawn.slick.SlickException
java_import org.newdawn.slick.AppGameContainer

class PongGame < BasicGame
  def render(container, graphics)
    graphics.draw_string('RubyPong (ESC to exit)', 8, container.height - 30)
  end

  def init(container)
  end

  def update(container, delta)
    input = container.get_input
    container.exit if input.is_key_down(Input::KEY_ESCAPE)
  end
end

app = AppGameContainer.new(PongGame.new('RubyPong'))
app.set_display_mode(640, 480, false)
app.start

Make sure it runs, then move on to fleshing it out.

A Background Image

It’d be nice for our game to have an elegant background. I’ve created one called bg.png which you can drag or copy and paste from here (so it becomes /mygame/bg.png):

Now we want to load the background image when the game starts and render it constantly.

To load the game at game start, update the init and render methods like so:

def render(container, graphics)
  @bg.draw(0, 0)
  graphics.draw_string('RubyPong (ESC to exit)', 8, container.height - 30)
end

def init(container)
  @bg = Image.new('bg.png')
end

The @bg instance variable picks up an image and then we issue its draw method to draw it on to the window every time the game engine demands that the game render itself. Run pong.rb and check it out.

Adding A Ball and Paddle

Adding a ball and paddle is similar to doing the background. So let’s give it a go:

def render(container, graphics)
  @bg.draw(0, 0)
  @ball.draw(@ball_x, @ball_y)
  @paddle.draw(@paddle_x, 400)
  graphics.draw_string('RubyPong (ESC to exit)', 8, container.height - 30)
end

def init(container)
  @bg = Image.new('bg.png')
  @ball = Image.new('ball.png')
  @paddle = Image.new('paddle.png')
  @paddle_x = 200
  @ball_x = 200
  @ball_y = 200
  @ball_angle = 45
end

The graphics for ball.png and paddle.png are here. Place them directly in /mygame.

We now have this:

Note: As I said previously, we’re ignoring good OO practices and structural concerns here but in the long run having separate classes for paddles and balls would be useful since we could encapsulate the position information and sprites all together. For now, we’ll ‘rough it’ for speed.

Making the Paddle Move

Making the paddle move is pretty easy. We already have an input handler in update dealing with the Escape key. Let’s extend it to allowing use of the arrow keys to update @paddle_x too:

def update(container, delta)
  input = container.get_input
  container.exit if input.is_key_down(Input::KEY_ESCAPE)

  if input.is_key_down(Input::KEY_LEFT) and @paddle_x > 0
    @paddle_x -= 0.3 * delta
  end

  if input.is_key_down(Input::KEY_RIGHT) and @paddle_x < container.width - @paddle.width
    @paddle_x += 0.3 * delta
  end
end

It’s crude but it works! (P.S. I’d normally use && instead of and but WordPress is being a bastard – I swear I’m switching one day.)

If the left arrow key is detected and the paddle isn’t off the left hand side of the screen, @paddle_x is reduced by 0.3 * delta and vice versa for the right arrow.

The reason for using delta is because we don’t know how often update is being called. delta contains the number of milliseconds since update was last called so we can use it to ‘weight’ the changes we make. In this case I want to limit the paddle to moving at 300 pixels per second and 0.3 * 1000 (1000ms = 1s) == 300.

Making the Ball Move

Making the ball move is similar to the paddle but we’ll be basing the @ball_x and @ball_y changes on @ball_angle using a little basic trigonometry.

If you stretch your mind back to high school, you might recall that we can use sines and cosines to work out the offset of a point at a certain angle within a unit circle. For example, our ball is currently moving at an angle of 45, so:

Math.sin(45 * Math::PI / 180)   # => 0.707106781186547
Math.cos(45 * Math::PI / 180)   # => 0.707106781186548

Note: The * Math::PI / 180 is to convert degrees into radians.

We can use these figures as deltas by which to move our ball based upon a chosen ball speed and the delta time variable that Slick gives us.

Add this code to the end of update:

@ball_x += 0.3 * delta * Math.cos(@ball_angle * Math::PI / 180)
@ball_y -= 0.3 * delta * Math.sin(@ball_angle * Math::PI / 180)

If you run the game now, the ball will move up and right at an angle of 45 degrees, though it will continue past the game edge and never return. We have more logic to do!

Note: We use -= with @ball_y because sines and cosines use regular cartesian coordinates where the y axis goes from bottom to top, not top to bottom as screen coordinates do.

Add some more code to update to deal with ball reflections:

if (@ball_x > container.width - @ball.width) || (@ball_y < 0) || (@ball_x < 0)
  @ball_angle = (@ball_angle + 90) % 360
end

This code is butt ugly and pretty naive (get ready for a nice OO design assignment later) but it’ll do the trick for now. Run the game again and you’ll notice the ball hop through a couple of bounces off of the walls and then off of the bottom of the screen.

Resetting the Game on Failure

When the ball flies off of the bottom of the screen, we want the game to restart. Let’s add this to update:

if @ball_y > container.height
  @paddle_x = 200
  @ball_x = 200
  @ball_y = 200
  @ball_angle = 45
end

It’s pretty naive again, but does the trick. Ideally, we would have a method specifically designed to reset the game environment, but our game is so simple that we’ll stick to the basics.

Paddle and Ball Action

We want our paddle to hit the ball! All we need to do is cram another check into update (poor method – promise to refactor it later!) to get things going:

if @ball_x >= @paddle_x and @ball_x < = (@paddle_x + @paddle.width) and @ball_y.round >= (400 - @ball.height)
  @ball_angle = (@ball_angle + 90) % 360
end

Note: WordPress has borked the less than operator in the code above. Eugh. Fix that by hand 😉

And bingo, we have it. Run the game and give it a go. We have a simple, but performant, video game running on JRuby.

If you’d prefer everything packaged up and ready to go, grab this archive file of my /mygame directory.

What Next?

Object orientation

As I’ve taken pains to note throughout this article, the techniques outlined above for maintaining the ball and paddle are naive – an almost C-esque approach.

Building separate classes to maintain the sprite, position, and the logic associated with them (such as bouncing) will clean up the update method significantly. I leave this as a task for you, dear reader!

Stateful Games

Games typically have multiple states, including menus, game play, levels, high score screens, and so forth. Slick includes a StateBasedGame class to help with this, although you could rig up your own on top of BasicGame if you really wanted to.

The Slick wiki has some great tutorials that go through various elements of the library, including a Tetris clone that uses game states. The tutorials are written in Java, naturally, but the API calls and method names are all directly transferrable (I’ll be writing an article about ‘reading’ Java code for porting to Ruby soon).

Packaging for Distribtion

One of the main reasons I chose JRuby over the Ruby alternatives was the ability to package up games easily in a .jar file for distribution. The Ludum Dare contest involves having other participants judge your game and since most participants are probably not running Ruby, I wanted it to be relatively easy for them to run my game.

Warbler is a handy tool that can produce .jar files from a Ruby app. I’ve only done basic experiments so far but will be writing up an article once I have it all nailed.

Ludum Dare

I was inspired to start looking into JRuby and Java game libraries by the Ludum Dare game development contest. They take place every few months and you get 48 hours to build your own game from scratch. I’m hoping to enter for the first time in just a couple of days and would love to see more Rubyists taking part.

A Lagom Review of O’Reilly’s ‘Sinatra Up and Running’

Sinatra Up and Running is a new book published by O’Reilly and written by Alan Harris and Konstantin Hasse that covers the popular Sinatra web application DSL in a brisk 103 pages, acting as a tutorial to newcomers and a handy reference for old hands.

TLDR: It’s a short, sweet, relatively cheap and very well written book about Sinatra. Recommended. Buy here.

An interesting quirk of Scandinavian society is the concept of Jante Law. It knocks down standing out and being individual, in favor of communal harmony. It’s typically used in a negative context to lament restrictions and lack of risk taking within Nordic society (DHH touched on this briefly in a recent Mixergy interview) but the flip side of the Jante coin is lagom: the idea and ideal of having just the right amount of something.

Sinatra Up and Running is, second to K&R, the most lagom technical book I’ve read. At a mere 102 pages you may wonder whether it’s worth buying – it is. Unlike most technical books – yes, including mine – it skips the waffle and provides a perfect level of detail going through from what Sinatra is, to how it works, and on to an example project that covers just 13 pages. Don’t be fooled, though, this isn’t one of those tiny format O’Reilly handbooks; it’s a regular, full size book – just a thin one!

Structure

The book is split into three key sections:

  1. Sinatra’s “fundamentals.” We cover similar ground to the Sinatra README but I prefer the less generic examples in the book. How to build routes, use views, use sessions, caching, HTTP headers, and even Sinatra 1.3’s new streaming functionality.
  2. Behind the curtain. The bulk of the book takes a peak under the kimono into areas where online documentation occasionally trips over or fails to mention. How is Sinatra implemented and what is its basic execution model? How do you create extensions for it? How does it integrate with Rack middleware? And how can you use Sinatra in a modular style?
  3. Blog engine project. A snappy run through a simple Git and Sinatra powered ‘blogging’ system.

As a core piece of printed documentation for a project, the book does a great job at sharing the basics, inspiring you to dig further and, of course, its short length puts Sinatra into context with the gargantuan Rails framework, where even a 400 page book would struggle to cover the essentials.

So, should you buy it?

Sinatra Up and Running is a good book and well written. I enjoyed it and picked up or was reminded of quite a few interesting bits and pieces. I’ll probably refer to it from time to time. If your Sinatra experiences are rather on and off or you’ve not played with it for a while, it’s a great, well-paced introduction.

If, however, you’re already a Sinatra guru and/or working with Sinatra on a day by day basis and have all of the main patterns memorized, there’s not a great deal you’re going to get out of it. Buy it to be a completionist or to support the authors, but if you want a book demonstrating in depth how to integrate Sinatra with everything or how to big giant Web applications, this isn’t for you.

Inexperienced Rubyists may also find the book’s direct no-nonsense style intimidating. If you know what a code block is, you’re good to go. This may seem like a bizarre observation to most Rubyists, but I’ve encountered many beginners who’ve wanted to “build a Web site” and immediately leapt into an advanced Rails book, only to be confused. If you’re still new to Ruby, read The Well Grounded Rubyist or Beginning Ruby first.

And I’m going to stop here, because that would be lagom 🙂

Where to buy

There are several options for buying the book. Check out O’Reilly (print, PDF, Mobi, and ePub), Amazon.com (print and Kindle), and Amazon.co.uk (print and Kindle) or your own favorite local bookstore.

iOS SDK Development; Cutting an Agile Groove Full Series released

iOS SDK Development now in beta; Cutting an Agile Groove Full Video Series released

Ludum Dare for Rubyists: An Online 48 Hour Game Coding Competition

Ludum Dare is an online accelerated game development event that focuses on regular 48 hour competitions. Think Rails Rumble but for games! It’s been around since 2002 but has had a big publicity boost recently due to the participation of Notch, the creator of the mind-bogglingly popular indie game Minecraft.

The next Ludum Dare contest is taking place this coming weekend between December 16-19, 2011 and I want to encourage Rubyists to take part. The competition tends to be dominated by Java, Flash, Microsoft XNA developers, and HTML5 developers, so it’d be great to see more Ruby entries (of which there have only been a couple so far).

During August’s event, I, along with hundreds of others, was glued to Notch’s livestream watching him code his game, Prelude of the Chambered (a 6 minute version is on YouTube). I was inspired enough to port his Java code into Ruby using JRuby, producing
potc-jruby (sadly far slower than the original Java version). This time, I plan to enter for real and build my own original game.

How to Take Part in Ludum Dare

Go to the Ludum Dare homepage, read the rules and guide, register on their WordPress blog, wait until the ‘theme’ has been decided, and start coding once the countdown is finished.

During the 48 hours (or 72 if you do the ‘jam’ version), you can post blog entries directly to the main Ludum Dare site (if you want) and submit your entry via a special link at the end. Entrants play and judge each other’s entries for a period of three weeks before the winners are announced. Having more Rubyists involved would be useful since our games may be less likely to work cross platform or without Ruby installed.. (more on this shortly)

A quick summary of the rules:

  • You have to work alone. (If you want to do a team effort, you need to enter the less restrictive ‘jam’ contest.)
  • All content and code must be created within the 48 hours (except for libraries, legally licensed fonts and drum/instrument samples).
  • Your game has to be based on the theme given out before the contest.
  • You must share the source code with the other participants at the end of the contest though you do not have to give it an open source license.

The contest has a popular IRC channel (which is already quite active) at #ludumdare on irc.afternet.org. I’m petercooper on there – say hi! I’ll be lurking in there a lot over the next week.

Building a Game in Ruby?

Building games in Ruby isn’t popular but it’s not frontier country either. Rubystein, a Wolfenstein 3D pastiche by the Phusion guys, remains a favorite of mine and it even runs on 1.9 with only a few tweaks.

There’s a great series by Andrea Wright that dates from 2007 but still has some handy pointers. We also have Ray, RubyGame, and Gosu which all have their fans (Ray is the most recent Ruby game library I’m aware of).

Or.. JRuby!

My choice for the contest is none of the above. Instead, it’s JRuby. As part of the ‘warmup process’ for the contest, I’ve been playing with JRuby and the popular Slick2D Java library. The performance is amazing and the development process pretty straightforward.

Being a popular library in the Java world, I can use a lot of the Java-based tutorials and code samples for Slick2D to get a feel for how it all works. And.. I’ll be writing an article for Ruby Inside in the next day or two showing you how to get started with it for yourself 🙂

Skipping Asset Compilation with Capistrano

Capistrano has a handy task that runs rake assets:precompile for you when you are deploying your Rails 3.1 application. This gives you an easy way to get the performance boosts of having only one css file and one javascript file to load per request. The price you pay for that benefit is the amount of time it takes to run that rake task when you are deploying. There is a way to get the benefit while reducing that cost, though.

Since capistrano creates a symlink for the assets that is moved across deploys, you really don’t need to compile those assets for any deploy where the assets didn’t change. Instead, all you need to do is move the symlink. However, the default capistrano for compiling the assets does compile them every time, regardless of whether any assets were changed in the set of commits that you are deploying. The Continue reading “Skipping Asset Compilation with Capistrano”

Skipping Asset Compilation with Capistrano

Capistrano has a handy task that runs rake assets:precompile for you when you are deploying your Rails 3.1 application. This gives you an easy way to get the performance boosts of having only one css file and one javascript file to load per request. The price you pay for that benefit is the amount of time it takes to run that rake task when you are deploying. There is a way to get the benefit while reducing that cost, though.

Since capistrano creates a symlink for the assets that is moved across deploys, you really don’t need to compile those assets for any deploy where the assets didn’t change. Instead, all you need to do is move the symlink. However, the default capistrano for compiling the assets does compile them every time, regardless of whether any assets were changed in the set of commits that you are deploying. The trick, then, is to check the list of files that were changed in the range of commits that are being deployed, and compile the assets only if assets show up in that list. And here is a code snippet that does exactly that:

It only supports git, as that’s what I use, so if you use git, just drop that snippet into deploy.rb and enjoy quicker deployments.