Setting headers in Ruby's CGI library

It seems like an easy enough question - how do you set HTTP headers using Ruby's CGI library? The pickaxe book has a quick mention of setting a cookie, which is effectively the same thing, but I couldn't seem to find a discussion of general headers; in particular, the caching headers. The following code sample is a trivial CGI that shows how to set the Expires and Cache-Control headers (setting expiration to 24 hours from now):

require 'cgi'
cgi = CGI.new()
cgi.out( "Expires" => CGI.rfc1123_date(Time.new + 86400),"Cache-Control" => "max-age=86400" ) {
  puts "Hello, World!"
}

The syntax of the dictionary you pass as an argument to out looks a bit funny to me. It's a literal dictionary without the surrounding curly braces. Still, it works, so I'm not arguing with success.

— Gordon Weakliem at permanent link

Hashed Thoughts

public partial class MainForm : Form
{
   private Dictionary bathroomMapping = new Dictionary();

   public MainForm()
   {
      bathroomMapping.Add(0.0, 0);

I was writing something for work today and ran into a situation where I needed to map between a decimal value and an integer index, so I did the obvious thing and created a mapping from Decimal to int, then initialized my mapping to the documented values. Except that I forgot that Decimal literals take an "M" suffix, which yielded the error "Argument '1': cannot convert from 'double' to 'decimal'", so I had to go back and edit my list of 20-odd mappings to fit. A 30 second fix, but enough time for me to wonder, again, why a DWIM system couldn't be applied here. Maybe under the refactoring menu? Suggest a correction, and then say "Apply this change to all other errors of this type?". Probably not enough dumb programmers out there to justify it. Maybe I should write a Visual Studio macro.

It occurs to me again one of the salient features of the languages I really like: syntax for declaring literals of complex types. .NET 2.0 has syntax for declaring literal arrays, but hashtables are so much more useful.

# ruby
brMapping = { 0.0 => 0, 1.0 => 1, 1.5 => 2 }
# python
brMapping = { 0.0 : 0, 1.0 : 1, 1.5 : 2 }
; scheme
(define br-map '((0.0 . 0) (1.0 . 1) (1.5 . 2)))

Of course, the scheme version is an assoc list, not a true hashtable. Still, define-syntax can fix that. PLT Scheme offers the #hash macro around the PLT-specific hash-table type, which would amount to substituting #hash for the quote character above. Lisp... if you don't like the syntax, write your own.

Another problem with my example is that all of these languages will treat literals like 1.5 as floating point types. In this case, I have exact quantities, so this is not exactly bulletproof code (12 years ago, I spent half a day in the debugger trying to figure out why the computer would not believe that 0.0 == 0.0, so I have a hard-earned appreciation for floating point inexactness). Why is floating point the default type for literals, which are defined precision by their very nature? You're declaring a fixed number of digits. Floating point seems to me to be more of a special case than fixed point.

— Gordon Weakliem at permanent link

Experiments, Part II

I've still been casting about, trying to find something more interesting to do with the Google Feeds API. I had a vague idea about somehow integrating feed data with a commercial source like Amazon - maybe a low-rent version of Amazon ads. So I thought about ways to use content to drive suggestions. What I realized was that it wasn't all that interesting to simply redisplay content - I wanted to derive something else off that content. What I arrived at was a sort of photostream of books related to content. You can read more about the technical details of the approach on that page. What I don't like is how I'm still using categories to drive keywords; this seems like a weak technique. I'd like to do another iteration along the same lines, but doing some more interesting analysis of the text of the posts coming from the feeds API to generate Amazon images and links. Of course, you could probably do different image sources - flickr, or Google Images, for example. I'd also like to tweak the stylesheet to make the display nicer. It's been fun doing this as a diversion. I've learned a lot about Javascript - it behaves in ways that sometimes surprised me. I've also been doing a bit of Ruby in the last couple weeks, my first time actually using that language for anything more than following a tutorial.

— Gordon Weakliem at permanent link