All posts by Brian Morearty

ActiveRecord Now Supports an Identity Map. Hooray!

I just read that support for an identity map has just been merged into ActiveRecord. This has been a long time coming and I’m really happy it’s here. Huge thanks to Emilio Tagua for doing this.

In some of my projects an identity map would have saved a lot of ugliness. I’m going to start using this feature in small projects as soon as it’s released. Once it has proven itself to me it will become part of my app template for all my projects. (It’s turned off by default, which seems reasonable for now.)

Read more about it in the link above.

How to Set a Time Zone for Each Request in Rails

The Railscast on Time Zones has some sample code that lets you set a thread-local, per-request time zone with a before_filter:

# controllers/application.rb
  before_filter :set_user_time_zone

  private

  def set_user_time_zone
    Time.zone = current_user.time_zone if logged_in?
  end

Problem is, the current user’s time zone will leak across to the next request on the same thread. If the next one is by a logged-out user, all times displayed on that next request will show in the first user’s time zone.

To prevent this, use an around_filter:

  around_filter :set_time_zone

  private

  def set_time_zone
    old_time_zone = Time.zone
    Time.zone = current_user.time_zone if logged_in?
    yield
  ensure
    Time.zone = old_time_zone
  end

You might be tempted to combine the first two lines of set_time_zone into one line with the comma assignment syntax and add “if logged_in?” to the one line in the ensure clause. Don’t do it. If you did that, the user’s time zone would leak out to the next request when the user logs out.

I’ve submitted a Rails patch to use this method in the sample code for the Time.zone= docs.

How to fix Ruby error: Unsupported digest algorithm (sha256).

This is a note to myself because this has happened to me more than once. I’m posting it publicly in case it helps others, too.

This is for people on a Mac, using rvm and homebrew.

I ran across this with the very nice Sucker gem, which lets you easily access the Amazon Product Advertising API. Amazon requires SHA-256 in its API calls, which is where my trouble began.

If your Ruby app got this error message in openssl/digest.rb:55:

Unsupported digest algorithm (sha256).

it’s because when you installed (compiled) Ruby, you linked in an older version of the openssl library.

I Like Stuff that Finally Worked

Here’s how I fixed it:

brew install openssl
rvm remove 1.8.7
rvm install 1.8.7 --with-openssl-dir=/usr/local/Cellar/openssl/0.9.8o/

To test it, run this in the Terminal:

ruby -ropenssl -e 'p OpenSSL::Digest::Digest.new("sha256")'

If you don’t get an error message, it worked.

Things That Didn’t Work

Installing and building openssl from source (openssl.org) did not work.

Installing the openssl rvm package and removing+reinstalling ruby did not work.

What finally worked was the steps above. Woo hoo!

By the way, I did not have to upgrade to Snow Leopard.

What about Ruby 1.9.2?

I still haven’t gotten it working in Ruby 1.9.2. I run this:


rvm install 1.9.2 --with-openssl-dir=/usr/local/Cellar/openssl/0.9.8o/

and I get this output:


ruby-1.9.2-p136 - #fetching
ruby-1.9.2-p136 - #extracted to /Users/Brian/.rvm/src/ruby-1.9.2-p136 (already extracted)
ruby-1.9.2-p136 - #configuring
ruby-1.9.2-p136 - #compiling
Error running 'make ', please read /Users/Brian/.rvm/log/ruby-1.9.2-p136/make.log
There has been an error while running make. Halting the installation.

So I go look in make.log and I see this at the end:


Generating RDoc documentation
./miniruby -I./lib -I.ext/common -I./- -r./ext/purelib.rb  ./tool/runruby.rb --extout=.ext  -- "./bin/rdoc" --no-force-update --all --ri --op ".ext/rdoc"  "."
/Users/Brian/.rvm/gems/ruby-1.8.7-p330/gems/rdoc-3.4/lib/rdoc/rdoc.rb:79: warning: already initialized constant GENERATORS
uh-oh! RDoc had a problem:
undefined method `coverage_report' for #<RDoc::Options:0x7841a0>

Does anyone know how to fix it?

Teaching my 12-Year-Old Daughter to Program, Part 3

Martin Luther King Day was a holiday for both my daughter’s school and my employer. The three-day weekend gave us both enough of a break that we got back to our previously-scheduled programming lessons—and this was a fun one!

(You may notice that the title of this post has a small difference from the earlier ones. Since the last post a couple weeks ago, Rosey has turned 12.)

Calling ‘puts’ over and over again is alright, but there’s nothing more fun for a fledgling programmer than asking the user a question, getting the answer, and then writing back a witty reply. In Chapter 4 of Learn to Program, Rosey learned about variables and assignment but the real fun came in Chapter 5, when she learned how to call gets to get a string from the user and then use the String.+ method to write back that string in the middle of a response.

Near the beginning of the chapter, though, I decided to take a detour and explain computer memory. This is the sentence in the book that triggered this:

“To store the string in your computer’s memory for user later in your program….”

The words “store the string in memory” reminded me of something I can still clearly remember: way back when I was 14 or so and first learning to use WordStar on my family’s Osborne 1, I found it hard to understand the difference between “Open” and “Save.” The picture in my mind of what’s going on inside the computer was extremely vague. I didn’t understand the difference between RAM and the Hard Drive, and why the word Open should mean moving something from the hard drive to RAM and Save should mean moving something from RAM to the hard drive.

I’m a believer in remembering what I struggled with in a subject, and trying to explain those things when I teach the subject. I hope that makes me a better teacher.

Computer Memory

RAM vs. HD, Open vs. Save...and the BRAIN

So I quickly sketched the attached diagram, explaining the pieces as I went. As I suspected, the difference between RAM and HD was pretty abstract for her and took some time even though she is an experienced game player. She got it, though, and we moved on the fun stuff.

The chapter on variables and assignment was surprisingly easy. The first few pages of the next chapter (Chapter 5, “Mixing it Up”) were useful for her as well, although not incredibly exciting. They explained things like why you can’t do ‘5’ + 5, and why ‘99.999’.to_i returns 999.

But this was all just leading up to the awesome part. In section 5.3 the book introduces the gets function, and in 5.5 you ask the user’s name and then print it back in a sentence. Rosey was so excited the first time she ran that. It was fun to watch.

Finally she did the exercises for the chapter, which were really kid-friendly. The first one tells you to write a program that asks for a person’s first, middle, and last names and then greets the person using their full name. She had fun with that, writing out prompts like “That’s an…um, interesting middle name.” And the next exercise was cute: ask for a person’s favorite number, add one to it, and tactfully suggest that as a better favorite number because it’s bigger. She got the essence of the program right on the first try but she was missing the conversion between strings and numbers. I made sure not to point out the errors as she was typing. I think that was the right approach, because the interruptions might have prevented her from getting the basic logic down right.

One last thing to note: I remember being confused about the assignment operator when I learned to program, and she was too. In particular, she thought the value should go on the left and the assigned variable should go on the right:


fav_number + 1 = new_fav

Take the programmer part out of your brain and read that code out loud. It makes sense, doesn’t it?

“Favorite number plus one equals the new favorite number.”

But alas, the computer doesn’t think so. She grudgingly accepted that and moved on.

I’m not sure when our next lesson will be. Hopefully sooner than the next holiday, since that’s in May. 🙂

See you all next time….

Quick and Dirty Performance Profiling in Ruby

Occasionally I read Rails source code to learn/re-learn what it’s capable of.

Want to do some quick and dirty profiling to see how long some Ruby code takes? Do this in irb or in a Ruby project:

require 'rubygems'
require 'active_support/core_ext/benchmark'

puts Benchmark.ms do
   # put your code here
end

The output is how long in milliseconds the code took to run.

This requires ActiveSupport but does not require all of Rails. If you don’t have ActiveSupport, install it with gem install activesupport.

JSConf 2011: See How Twitter Built a Single-Page Web App

I just submitted my proposal to speak at JSConf 2011 in Portland on May 2-3. Well actually I don’t plan to fill both entire days.

My title: “Exposing New Twitter’s Secrets (Without a TSA Full Body Scan).”

Want to build your own single-page web app? If my proposal is accepted, come attend my talk and we’ll reverse-engineer New Twitter to see how they did it. Maybe you will get some good insight and ideas.

Teaching my 11-Year-Old Daughter to Program, Part 2

In my last post I said I am starting to teach Ruby to my daughter Rosey. So today after getting back home from watching Tangled in 3D we got started. She had done the first reading assignment last night (Preface, Intro, and Chapter 1 of Learn to Program). Our next step was to sit down and follow the instructions in Chapter 1, which was about installing and setting up the environment.

First I had to set some ground rules. Well, one ground rule:

Let’s stay on topic.

Kids always want to tell you random things. Unless they’re teenagers, of course, in which case I’m told they close off in their room for about four years. So I gave her a piece of paper and a pencil. If she thought of anything unrelated to programming that she was dying to tell me, she could write a reminder to herself on the paper and tell me later. I think it helped. At one point she was juuuuuuuuuuuuust about to tell me something but she caught herself and just wrote it down. I think having this release valve helped get the idea out of their head so she wouldn’t be distracted and could concentrate.

So, down to work. We installed Ruby on her laptop with the Ruby One-Click Installer. Yes, it’s her laptop even though we have three kids. Each kid has their own laptop. Refurbished corporate PCs are pretty cheap. And we installed Notepad++ too, since I love it.

Rosey had fun playing with the echo command on the command line, echoing everything I said. Having a computer do this is only slightly less annoying than having a person do it. Then she did this at the prompt:

C:>:-)

And to our surprise, there was no error message. It just came back with another C: prompt. I guess that’s because in the Windows batch language a line that starts with a colon is a label—and you can put anything you want after it. Fun.

We finished Chapter 1 in a hurry and I was worried it wasn’t the best first day. Fortunately, she said yes when I asked if we could just do the first two paragraphs of Chapter 2 since I saw that’s where the instant gratification begins. She was hooked after this worked:


puts 1 + 2 # => 3

She experimented with some other math. I told her about * and / for times and divided by, and she did:


puts 300 / 8

but was surprised when the program printed 37 instead of 37.5. At that point I became pretty impressed with the order in which the book introduces new concepts, because I had read ahead and knew that the next page describes integers vs. floats, and goes on to explain why integer math always returns an integer. We read through it, typed in the examples, and were having fun. The book impressed me with its clairvoyance again when Rosey got tired of typing the spaces between the mathematical operators and asked if they are really needed. I showed her the next paragraph, which said “the spaces in the program are not important; they just make the code easier to read.”

Rosey also tried one of her favorite phrases:


puts I like pie

but she got an error message because she doesn’t know yet that strings have to be quoted. (The command-line echo command didn’t need them.) I decided not to bother explaining that for now, since the next chapter goes into it.

At one point the book said, “Don’t type commas into your numbers” because it just confuses Ruby. But I taught her a little-known Ruby trick, using underscores where you would have used commas. She’s learning ancient ninja secrets.


puts 1_000_000

I thought the exercises at the end of Chapter 2 would be hard. They ask the reader to solve problems like “How many hours are in a year?” and “How many seconds old are you?” It turned out they were a piece of cake. She raced through them, stopping only a few times to figure out whether to divide or multiply.

Next up: Rosey’s next reading assignment is Chapter 3, “Letters,” which talks about strings. Christmas vacation is over and school starts up tomorrow, so her homework will take precedence. But hopefully we’ll be able to keep the pace going and not lose steam.

So far so good!

Teaching my 11-Year-Old Daughter to Program (in Ruby)

This is installment #1 in a series of posts I will write about teaching my 11-almost-12-year-old daughter to program in Ruby.

In the last year I taught my daughter Rosey, who is 11 years old and in sixth grade, the basics of HTML. With help and training from me she made a few web pages with her own drawings, including some clever puzzles. We hand-coded all the pages instead of generating them with a drag-and-drop tool. That was her choice. (Hooray!)

She came away knowing some HTML. She knows it well enough to give a bit of an explanation to her friends, which I think is awesome. I tried to teach her a bit of CSS and JavaScript too. She may have had an inkling of how they work, but I didn’t do a very good job on those parts. I think it was mainly because I didn’t have a structured way to teach them. I admit I was pretty much all over the map. HTML was easy to teach tag by tag–start with <html>, <body>, <p>, and <img>. But with JavaScript to do anything useful on a website you have to go quickly past the basics and understand functions, the DOM, and more. I ended up writing the JavaScript myself and hoping she’d at least know it exists so she could come back some day.

Now it’s a new year, and next week she’ll turn 12. I asked her if she’d like to learn to program in a language that can actually make things happen instead of just show things on a page. Somehow I must have used just the right combination of excitement and pleading, because she said yes.

Very cool. I get to teach my daughter to write software! I’ve been waiting for this day for a long time. Almost 12 years.

She already knows a couple of boys her age who have started learning to program but most of the boys have not. I’m excited that she will be ahead of a lot of the boys, since I hear one reason girls are sometimes behind in learning computer stuff is the intimidation factor: they take a class and see that most of the boys have already learned a lot of it on their own, so the girls feel like they’ll never catch up. I totally get that, and want to prevent it.

I Like Stuff that’s Ruby

Decision #1: what language to teach? I wanted to teach an interpreted language because interactive interpreters make learning easier. I primarily considered JavaScript and Ruby. I think they’re both great choices because (a) they’re both interpreted, (b) neither requires an immediate understanding of object-orientation, (c) I know them both really well and love them both, and (d) they’re actually useful.

I also considered “kid” languages like Scratch or Logo. But I’ve tried Scratch and honestly I didn’t get it. If I don’t get it, how am I going to teach it? I did learn Logo years ago and it was fun. But I was more excited about teaching JavaScript or Ruby.

A couple years ago while browsing the Programming section of Borders Books in Palo Alto I noticed Chris Pine’s book, Learn to Program, and wondered if it would be good for a middle-schooler. I read more about it, and found a review titled “Great for Kids.” The author is using Learn to Program to teach their 8-year-old daughter and loves it. Plus I learned that the author actually teaches programming to kids my daughter’s age. That’s good enough for me! So I got the book and will start teaching her to program.

(By the way, if you haven’t been to Border’s on University Ave. in Palo Alto, do yourself a favor and go inside. It’s cool. It was a beautiful, classic movie theater called The Varsity when I moved to downtown Palo Alto in 1988. Later they converted it to a bookstore but they kept the marquee.)

Lesson 1

So Today I went out and picked up the book. No way could I wait for an Amazon shipment. Then I read the Preface, Introduction, and Chapter 1. Then I asked her to start with the Preface and read for 20 minutes or so and stop wherever she is, or to finish Chapter 1 if she wants. She ended up stopping at the same spot as me. Tomorrow we’ll go over Chapter 1 together. It’s mostly just about installing Ruby and a text editor. But I’ll also go over some of the high-level concepts I remember being incredibly confusing to me when I first learned to program. Specifically:

  • When I type a line of code into the computer, how should I think of this in comparison with an English sentence? Is it Declarative? Imperative? Something else? (Fortunately I think she has learned these terms in school. If she hasn’t, I can quickly describe the differences.) I think for a beginner the easiest explanation is that all lines of code are imperative. More specifically, you are telling the computer what to do. When you say “print 3” it’s like telling someone else–someone who always follows orders–to print the number 3 on a piece of paper. Of course some computer programming statements are more like declarative, interrogative, or conditional statements. But the first thing a beginner learns is the imperatives like “print.” (I peeked ahead at Chapter 2 and it starts with “puts 1+2”.)
  • What is the difference between RAM and the hard disk? How should I think of “saving” or “opening” a file? My daughter has saved documents before but I don’t think she quite groks RAM vs. disk yet.

Expectations

I enter this adventure with excitement and high hopes but also realistic expectations. She may get bored quickly or feel it’s too hard. I’m going to do my best to keep it light, fun, and low pressure. But if it doesn’t work out, it’s no big deal. You have to try things, right?

I will continue to blog about this adventure. Stay tuned right here on the I Like Stuff Blog.

How to Lazily Find All Records in Rails 3 with Arel

To my surprise, Post.all in Rails 3 performs the query immediately. It does not do lazy loading, as Arel’s where method does.

def index
  @posts = Post.all     # not lazy; returns Array
end

It turns out this is by design. See Force loading – all, first & last.

So: what do you use if your view has fragment caching and you want your controller’s index method to delay the query until you’re sure you’ll need to use it?

At first I did this:

def index
  @posts = Post.where('1=1')  # returns ActiveRecord::Relation
end

But the documented way is to use the scoped method:

def index
  @posts = Post.scoped        # returns ActiveRecord::Relation
end

Another alternative I recommend, which lets you do lazy execution queries in any version of Rails: move the queries to helper methods.

Well, That Didn’t Last Long. Bye, SQLite.

I recently started a new project in Rails 3.0 and decided to try SQLite as the development database. In the past I’ve always used MySQL for my Rails projects. I’m hosting the app on Heroku so it’s PostgreSQL in production, making this my first time using SQLite and my first time using different databases in development and production.

At first I was having fun with SQLite. It’s lightweight, doesn’t use much memory, runs fast on a local dev machine. A single database is stored in a single file. No server to configure, no nothing. Nice.

But I gave up on it after about five days because of an annoying limitation that bit me twice: if you add a NOT NULL column (:null => false in your migration) to an existing table, SQLite requires you to specify a default value—even if the table is empty.

It makes sense to require a default value on a NOT NULL column if there are already rows in the table. All relational databases require that. But if you don’t want to specify a default and the table is empty SQLite shouldn’t force you to.

I found discussions where people suggested a workaround of “Can’t you just drop the table and create a new one? As the table is empty, you won’t be losing any data.” Sure, but it’s far more error-prone to recreate the table because it’s not an incremental change. You have to carefully reconstruct the table and all indexes from all past migrations, which became unwieldy for me even in a 5-day-old project. It really is more error-prone: I tried it and screwed up a couple of times. That was it for me, so I decided it’s time to switch back to MySQL for local development.

The other experiment—using different databases in local development and production—is still going fine. We’ll see what snags I hit that make me change my mind about that too. I still wouldn’t do that on a big project but this is a little ol’ thang.