Tuesday, April 22, 2008

5 Rails Tips

If you're not already watching Ryan Bates' screencasts at Railscasts.com, I strongly recommend it. They're really quite well done and interesting. He's running a contest, in which participants suggest 5 Rails tips. For my examples, I've decided to focus on areas that are either informed by ideas from functional programming (which this blog is ostensibly about), or areas in which Ryan and I have different approaches (or both). Here are my tips:


Use Module methods


Here's where I disagree with something Ryan said in his 101st Railscast, in which he suggests using Class (or instance) methods with variables over using Module methods. I prefer to use Module methods. Here's a typical (truncated) example:


module DisplayHelper

def self.get_stylesheets_by_request(request)
user_agent = request ? request.user_agent : nil
self.get_stylesheets_by_ua(user_agent)
end

def self.get_stylesheets_by_ua(some_user_agent)
return STYLESHEETS_FOR[:palm] if some_user_agent =~ %r[Palm]
STYLESHEETS_FOR[:normal]
end

end


Then, in the RSpec file:


describe %q[get_stylesheets_by_request] do
mobile = %w[mobile]
it %Q(should add the stylesheet #{mobile} for Palm browsers) do
user_agent = %q[Some Palm User Agent]
request = mock_model(Object, :user_agent => user_agent)
DisplayHelper.get_stylesheets_by_request(request).should == mobile
end
normal_browser = %w[normal_browser]
it %Q(should add the stylesheet #{normal_browser} for all other browsers) do
user_agent = %q[Some User Agent]
request = mock_model(Object, :user_agent => user_agent)
DisplayHelper.get_stylesheets_by_request(request).should == normal_browser
end
end


As I said above, Ryan and I have different preferences regarding Class vs. Module. I like having helper methods that are testable in a more "purely functional" paradigm, wherein we mock a request, but don't need to mess around within the base controller object or the like. We just pass our mock request model into the get_stylesheets_by_request method and take it from there. Either approach works, you may find that one or the other matches your own thought process more closely.


Use Constants


In the code example above, notice the use of the STYLESHEETS_FOR Constant, which we can define as follows:


STYLESHEETS_FOR = {
:normal => %w[normal_browser],
:palm => %w[mobile]
}


It gives us access to either normal_browser.css or mobile.css, as appropriate. This is a somewhat contrived example, but you could use whatever list of stylesheets you want for the values in each pair, expanding to customize for Safari, Epiphany, Opera, etc.

This technique could be used for any data that is unlikely to change in the course of an app running, but is not tied specifically enough to a given model to be stored in the DB. This allows you to avoid continually reconstructing never-changing local variables inside a method call. Some more realistic examples appear again in the MessageHelper tip below.


Return guards can simplify flow control


I loath if - elseif - else - end flow control, and strongly prefer return guards. It's a personal bigotry that I freely admit, because I think return guards make code more readable, shorter, and more in line with how I think. Here's a rewrite of Ryan's star_type method from Railscast #101 that uses return guards rather than an if block.


def star_type(value)
return 'full' if value > 1
return 'half' if value == 1
'empty'
end


You save 4 lines, and also comply with my enraged, semi-coherent rantings. You can also get some additional shrinkage with a ternary. Here's star_type again, with a ternary:


def star_type(value)
return 'full' if value > 1
value == 1 ? 'half' : 'empty'
end


You save a line. I find it more readable than the if block. That may be because I like reading Haskell code. Who knows. Again, your flow control preference mileage (or kilometrage) may vary.


DRY up your messages in a MessageHelper


I like to create a MessageHelper.rb file that contains my messages. I usually have several Constant Hashes that vary depending on the purposes of the message.


module MessageHelper

DESCRIPTION_OF_RESOURCE = {
:name_of_resource => %q[My description...]
}

EXPLAIN = {
:not_empowered_to_delete => lambda { |type| %Q[You are not empowered to delete a #{type}.] }
}

ERROR = {
:overlapping_blocks => %q[Overlapping blocks of time]
}

MESSAGE = {
:confirm_short => %q[Are you sure?],
:confirm_long => lambda { |x| %Q[Are you sure you want to destroy this #{x}?] },
:logout_successful => %q[You have been logged out.]
}

TITLE = {
:new => lambda { |x| %Q[Make a new #{x}] },
:owner => lambda { |x| %Q[Owner of #{x}] },
:show => lambda { |x| %Q[Show #{x}] },
}

end


These are obviously truncated. I use DESCRIPTION_OF_RESOURCE and EXPLAIN for hover explanations and the like. Notice also that the EXPLAIN and MESSAGE[:confirm_long] values are Procs, allowing you to reuse them abstractly. The purpose of the ERROR, MESSAGE and TITLE hashes should be obvious from their names.1 The main benefit of this practice is that you can conform to DRY principles, while also separating your messages logically according to what they'll be needed for.

Of course, you can wrap the use of each of these hashes inside helper methods, like explain, message, or what have you.

1(Maybe the purpose of TITLE isn't obvious: It's to facilitate link differentiation with <a> titles as per http://www.w3.org/TR/WCAG10-HTML-TECHS/#link-text.)


Use parallel (pattern-matching) assignments


Whenever assigning into multiple variables, it can often be helpful to do simultaneous parallel assignments using pattern matching. Here's an example from an RSpec file. I have a resource called Preceptor which has many Rotations, and a helper method called create_preceptor_and_rotations that does what you (hopefully) expect:


@preceptor, @preceptor_rotations = create_preceptor_and_rotations
@preceptor, discard__rotations = create_preceptor_and_rotations


In the first case, I want to use both @preceptor and @preceptor_rotations for some purpose. In the 2nd case, I want to keep the @preceptor, but the name of the rotations variable informs anyone reading the code that I don't care about the rotations in this particular spec instance. In both cases, I've done assignments into two variables simultaneously.

This sort of pattern is common in situations like this:


def some_method_that_takes_a_list(*args)
head, *tail = *args
# do some operations, maybe something recursive
return [head, tail]
end

Which returns as follows:

some_method_that_takes_a_list(7) -> [7, []]
some_method_that_takes_a_list(7, 8) -> [7, [8]]
some_method_that_takes_a_list(7, 8, 9) -> [7, [8, 9]]
some_method_that_takes_a_list([7, 8, 9]) -> [[7, 8, 9], []]
some_method_that_takes_a_list(*[7, 8, 9]) -> [7, [8, 9]]





So there's my list. These are all obviously fairly subjective points, but I find that these approaches work well for me, and my co-workers seem pretty agreeable to them. Maybe they'll work for you, too.

First-Class Procedures, Part I: naming by a variable

In section 1.3.4 of SICP, the authors discuss (after Christopher Strachey) the rights and privileges of first-class citizens of a programming language, justifiably praising Lisp for awarding first-class status to procedures.

The first few real posts here will explore this topic as it relates to some other languages. Are procedures first-class citizens of Ruby? How about Erlang, or even JavaScript?

Ruby



I'll start with Ruby, where the topic seems most controversial. I'll also start with the first condition that SICP suggests first-class citizens must satisfy: being nameable by a variable. Here's a sample irb session:


$ irb
irb(main):001:0> add1a = 1.method(:+)
=> #<Method: Fixnum#+>

On line 1, we identify a given procedure by the name add1a by using the method method to extract the action that is referred to when sending the :+ symbol as a message to the Fixnum 1. Ruby defines this operation as simple numeric addition, more or less, and the fact that we're grabbing this method from 1, as opposed to 42 or -6 acts as a closure, meaning that the extracted method remembers that the item to which its arguments should be added is 1, rather than 42 or any of the other instances from which we could have extracted our method. (Had we extracted the :+ method from a different instance, perhaps hello, world!, the operation wouldn't even have been defined as simple numeric addition, but that's another story).


irb(main):002:0> add1b = lambda { |x| 1 + x }
=> #<Proc:0xb7c8a638@(irb):2>

On line 2, we're identifying another procedure by the name add1b. This time, we're using lambda to construct the procedure, rather than extract a pre-existing method from an instance.


irb(main):003:0> add1c = Proc.new { |x| 1 + x }
=> #<Proc:0xb7c823c0@(irb):3>

On line 3, we're identifying yet another procedure by the name add1c. This time, we're using Proc.new rather than lambda, both of which create Proc objects.

None of these assignments of procedures into names would be terribly useful if they weren't callable.

irb(main):004:0> add1a.call(2)
=> 3
irb(main):005:0> add1b.call(2)
=> 3
irb(main):006:0> add1c.call(2)
=> 3

We see that all 3 of these named variables perform the expected operation when called. How does this compare with some other languages that are more definitively functional?

Lisp/Scheme



In deference to SICP, let's see how this operates in MIT Scheme:

$ mit-scheme
1 ]=> (define add1 (lambda (x) (+ x 1)))

;Value: add1

1 ]=> add1

;Value 11: #[compound-procedure 11 add1]

1 ]=> (add1 2)

;Value: 3

The theory is the same: we identify a procedure by the name (add1 in this case), and then call it (apply it to its arguments). Note, however, that calling the add1 procedure is slightly more straightforward in Scheme. We simply construct a list within parentheses such that the procedure to be called happens to be the first item, and the arguments to that procedure call are the remaining elements of the list. There is no need for a separate .call syntax. Ruby Procs can also be called without a .call method if one puts the arguments within [], rather than parentheses, but the main difference still stands, which is that the syntax of calling such a procedure differs (however slightly) from calling the built-in methods. Lisp fans who deride Ruby fans' claims of Ruby having first-class procedures point to this, not entirely without merit.

Erlang



Another language that fits very well within the functional paradigm is Erlang:

$ erl
Erlang (BEAM) emulator version 5.5.5 [source] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.5.5 (abort with ^G)
1> Add1 = fun(X) -> 1 + X end.
#Fun
2> Add1(5).
6

here, we define a named variable Add1 that holds the procedure functionally equivalent to all of our examples so far, the action of adding 1 to the argument. Here, the action of calling our new named variable as a function is more straightforward, reminiscent of Scheme. We simply provide the argument within parentheses, as one calls any function in Erlang. There is a slight difference, in that variables in Erlang are capitalized, while built-in functions are lowercase. Still, functions are clearly nameable in Erlang.

JavaScript



What about JavaScript? JavaScript is a language that has gotten a largely undeserved bad rap, largely due to some bad implementations and what is perhaps the worst and most misleading name in programming language history. None of this detracts from the language itself, which my good friend Aubrey Keus calls Scheme with syntax. JavaScript reminds me a great deal of Ruby, in that it makes heavy use of both object-oriented and functional paradigms. Let's take a look at some JavaScript code that Aubrey provided:


add1 = function(x) { return x + 1; }


Look at how trivial that is to do. All one has to do is call add1(2) and 3 is returned, as one would expect. Again, the act of calling such a function is closer to (indistinguishable from) calling a built-in function.

I would argue that in all of these languages, procedures (whether implemented under the hood as functions or methods) satisfy this first criterion of being a first-class citizen. You may disagree, thinking that the additional hoops to be jumped through in the Ruby calls are too egregious. I find that from a pragmatic perspective, it's not that big a deal for me.

I also think Hashes are more like functions than Arrays, but that's another story.

So what's with the name?

I'm about to start writing a series of short posts, each about the question of whether procedures are first-class citizens in Ruby, as well as some other languages. Look for those starting in a few days. However, some folks might not be aware of the pun that inspired the name of this blog.

There may or may not be a legendary organization called The Knights of the λ Calculus. I wouldn't claim to call myself a wizard, nor do I primarily work in Lisp or Scheme, so I'm clearly not a member of such an illustrious group. However, I'll make frequent references to topics discussed in SICP, the Wizard Book, so I equally clearly have certain aspirations in this direction. Hence the blog name.