I once read somewhere that you should only use the if or unless conditionals at the end of a statement if that statement usually occurs (i.e., the condition usually passes). Otherwise, you should put the conditional at the beginning. For example, this is good behavior, since @post would normally be an ActiveRecord object:
first_comment = @post.comments.first unless @post.nil?
While this is not, since @post is rarely nil:
redirect_to :action => 'list' if @post.nil?
This makes sense for readability, but I find myself writing one-off statements with conditionals at the end, similar to the one above, because I don’t want to clutter up my code with a three line block:
if @post.nil?
redirect_to :action => 'list'
end
The alternative that I have deemed “most correct” is to simply write this as one line. This can be done using the following syntax:
if @post.nil? then redirect_to :action => 'list' end
You can alternately replace then with a colon (:) but I think writing then is cleaner since it makes your code read like English. (I do wish I could get rid of that pesky end.)
So in the end, would you agree with this assessment, or should I just ignore that advice and simply use conditionals at the end of the statement?
A body of techniques for investigating phenomena and acquiring new knowledge, as well as for correcting and integrating previous knowledge. It is based on gathering observable, empirical, measurable evidence.
That’s how the venerable Wikipedia defines the scientific method. In one of my former careers, systematic observation (through tests and repeated replication of results) was inherent in our every activity. Yet when I took to learning programming, I somehow forgot that the these methods aren’t just useful for gathering knowledge about the natural world, but about everything—including the digital world.
This realization came to me as a little flash of light while reading my brilliant former instructor Mike Clark’s post titled ‘Are you there world?,’ which suggests testing as a first step in learning Ruby. For better or worse, this is actually the exact inverse of the way most of us learn languages and frameworks. Testing is usually one of those things that we intend to get around to someday but never quite take the time to learn properly—something to do at the nebulous “end” of your big project as a way of making sure things aren’t breaking in production. I had fallen into this trap as well. I learned Ruby mostly by randomly stumbling around, trying new things in attempts to build little sandbox projects. There was nothing systematic about this, nor was there any attention to replication of my results. (Most of it involved lots of browser refreshing.) Somehow, I had forgotten the scientific method as the path to knowledge.
Mike, however, advocates what could certainly be called a scientific approach to learning Ruby, based on what are effectively systematic, repeatable, language experiments. He challenges us to put the computer in charge of remembering all the experimentation we do when we’re first learning a language, by writing tests for all the new functionality in the language that we learn as we’re learning it.
Tests, after all, are statements of an expectation followed by a verification that the actual results of an operation evaluate to that expectation. When we’re first learning, we poke at Ruby with a stick (irb) and see how it reacts. Mike is merely suggesting making these observations systematic and repeatable—recording how the subject reacts for posterity so you’ll be able constantly to review and verify what you’re learning about it. Think of yourself as a scientific pioneer who has discovered a completely new and sophisticated organism (in our case, Ruby). Earn that lab-coat of yours: keep good records of your findings!
I’m going to stretch the concept of “replication” from the scientific method a bit here, but I think it also applies as a metaphor at least. The idea is that when you have language tests in place to record what you’ve learned, you always know when your knowledge becomes invalid. When your expectations fail, you have something new to learn. For example, things are in constant flux in the Rails core code base. In 2.0, old ways of doing things are going to start breaking. If you’ve kept a record from the beginning of everything you know about Rails (in the form of an executable test), all you have to do is update your version of Rails, run the test again, and you’ll know everything that you have to learn over again simply by seeing what fails.
I just have one objection to Mike’s article. His article is all about encouraging people to use Ruby’s built-in Test::Unit framework. As it happens, Test::Unit is the main reason I went so long without ever learning testing in the first place. It’s syntax is weird, ugly, and requires significant mental backflips in order to understand what you’re trying to express. This isn’t what we spoiled young Rubyists are accustomed to. Let’s take a look at a gently modified example from Mike’s article
1 2 3 4 |
def test_length string = 'abc' assert_equal(3, string.length) end |
For those of us used to expressions like 2.days.from_now, this reads as utter gibberish: “test length assert equal 3 string equaling ‘abc’ length” That doesn’t make sense in any dialect of Engrish, Franglais, or Spanglish I’m acquainted with. But there is no need to succumb to this aphasia virus; there’s hope.
That hope comes to us in the form of RSpec, the new hotness in the Ruby and Rails testing world. Now, I should preface my discussion of RSpec by warning that most of the people who like to write about RSpec are given to a certain form of intellectual onanism, which forces them to insist on all manner of esoteric precepts and justifications for their framework. Watch out in particular for citings of the Sapir-Whorf Hypothesis, which doesn’t relate to the House of Mogh but rather a unjustifiably baroque way of expressing the simple idea that the the sort of language we use affects the way we think. Put even more simply, it’s better when we express ideas in a way that makes sense.
And that’s really what RSpec is all about: expressing tests in a way that makes sense. Let’s rewrite our Test::Unit example in RSpec terms:
1 2 3 4 5 6 7 8 |
context "A String" do specify "Should return the number of characters it contains when sent the message 'length'" do string = "abc" string.length.should_equal 3 end end |
How does that read in English? Well, we could run the file from the terminal with spec ruby_spec.rb -cfs and we’d get a nicely formatted answer in the output.
A String
-Should return the number of characters it contains when sent the message 'length'
(In fact, if you do sudo gem install redgreen, you’ll even get that second line in green if its spec passes, or red if it fails.)
Or, alternatively, just read the code itself, “A string should return the number of characters it contains when sent the message ‘length’: string equaling ‘abc’, length should equal 3.” How does that compare to “test length assert equal 3 string equaling ‘abc’ length” Yes, it’s more verbose, but that’s because it actually expresses an intelligible idea.
Incidentally, this syntax gives us the added advantage of rendering us so pliant and at ease with tests (because they’re not expressed in such a weird backwards-thinking way) that it feels much easier actually to write them before we write the code we want to test. This test-first approach is something many of us believe to be a vastly superior way of doing software design (aka Behavior Driven Development, or BDD, aka Test Driven Development, or TDD). This delay-of-gratification approach to coding normally requires significant restraint and patience, but with RSpec, it just feels right. Expressing tests/specs/expectations (or whatever you want to call them) in an intuitive way makes it easier to think about how you want your application to behave, allows you to specify that behavior, and then test that it meets the specification in what feels like natural language.
As an aside, there are those who, in order to protect the new hotnessness of their respective fiefdoms, will flip their wigs at the mere suggestion that TDD and BDD are similar/interchangeable concepts. You’ll have to forgive their casuistry. They mean well.
Now that I have this whole new, completely intuitive way of expressing and testing expectations in Ruby, I find myself actually writing tests all the time, for everything. Both as a learning tool and as a design tool. Now, I’m working with my pals over at The Edge Case to learn more about its advanced features, like “mocking,” “stubbing” and other tricks to help me avoid those nasty Rails fixtures. So look for more reports from the frontiers of RSpec science here in the future.
Mike Clark is right: the scientific approach is the best way to gather knowledge (and by extension to learn Ruby). There has just been a little paradigm shift in our scientific approach. Give RSpec a try, and see if it doesn’t make that lab-coat fit a little more comfortably.
I stumbled today on an apparently little-known method in Rails, which solved a problem that has been vexing me for months: how to use helper methods from controllers/models/views/whatever other than the one you’re currently working in. No amount of Googling or begging for suggestions in the (mostly useless) #rubyonrails IRC channel could do me any good.
Ok, so on Lovetastic, we have an account dashboard which pulls together lots of information from different models. This dashboard (for now anyway) rests in AccountController. However, I want to use a formatting helper to display a human-friendly version of people’s subscription expiration dates, the code for which rests in SubscriptionHelper. And I don’t want to have to duplicate any code to do it.
The helper in question, natch, is associated with a separate controller, so its methods don’t get mixed into the AccountController. So I had been trying all sorts of stupid and ugly hacks to include that helper code cleanly into the AccountController’s dashboard view. I tried using shared partials, raw ruby includes, and a couple even more arcane backflips, to no avail.
Then, with hours of sufficiently creative Googling, I was able to turn up a super-tidy Rails Way™ to do this.
1 2 3 4 5 |
class AccountController < ApplicationController helper :subscription ... end |
And, bam. There you have it. You can now use all the helper methods in SubscriptionHelper anywhere in an AccountController template.
Who knew?
Ruby: Perfect for 1984
by jd
NotRocketSurgery is proud to bring you this time wasting tidbit: how to make 2 + 2 = 5.
1 2 3 4 5 6 7 8 9 10 11 |
class Fixnum alias_method :add, :+ def +(n) if self == 2 && n == 2 5 else add(n) end end end |
With IronPython out, it is now possible to create Windows applications utilizing the full .NET platform without breaking out of Python. I enjoy programming in Python almost as much as in Ruby, and I’m sure many people will agree that a lot of developers are going to be much happier now that they have the option to write in Python what they couldn’t before.
I was wondering if anything like this exists for OSX. I’m aware of the RubyCocoa project, with is an Objective-C bridge to Ruby. This allows you to write Objective-C applications in Ruby, which essentially means it allows you to write native OSX applications. This is not really the same thing as IronPython. We know that Apple is a supporter of dynamic languages. They include Ruby and Python in the current version of OSX, Tiger. They are even including Ruby on Rails support into the next version of Leopard Server.
Some googling digs this up: “support for script-to-framework programming is available, allowing Python and Ruby scripting to access Mac OS X specific APIs.” This forum post appears to be the source. I can’t really find any more information.
So… are we going to be able to write OSX applications in a dynamic language (hopefully Ruby!) when OSX Leopard comes out next year?
I was recently reminded of this piece of syntax:
ids = users.collect(&:user_id)
This is equivalent to:
ids = users.collect { |u| u.user_id }
The implementation is provided by a Rails extension to Ruby’s Symbol class and hence is not available in pure Ruby environments, like irb.
While clearly this is a handy shortcut, it makes your code quite unreadable for anyone who doesn’t understand the to_proc extension made by the Rails team—it is not inherently obvious what you’re doing. If your code is being maintained by multiple developers, is it really wise to use it?
For those of you wondering how this little trick works: the Rails team is exploiting the nature of duck typing in Ruby. When the & operator is used as a function parameter, you are telling Ruby to treat that parameter as the block passed to the function. In order to assure that the object is a Proc object, Ruby calls to_proc on all such parameters. Hence, the Symbol class has been extended by the Rails team to include a to_proc method. This method returns a Proc which calls the method by the same name as the symbol itself.




