Archive for the ‘Uncategorized’ Category

How to Free Up Inactive (Blue) Memory in Mac OS X

November 9, 2011

Want to turn Activity Monitor’s “blue” (inactive) memory to “green” (free) on your Mac without closing any programs?

Run Terminal and type:

  $ purge

My memory went from  to  the last time I did this. Not too shabby. (Why did it also clear up some Active Memory? I have no idea.)

That’s all you have to do. It can take up to a minute. While purge is running your system will be slow. After that, with all that free memory, it’ll be zippier than before.

Don’t listen to all the remarkably obnoxious fanboys or official Apple support pages telling you just to leave Inactive Memory alone because it will be freed up quickly if it is needed, or that the system knows better than you do when to free memory. Trust your experience. In my experience it will not and it does not. 

Here is the purge man page:

PURGE(8)                  BSD System Manager's Manual                 PURGE(8)

NAME
     purge -- force disk cache to be purged (flushed and emptied)

SYNOPSIS
     purge

DESCRIPTION
     Purge can be used to approximate initial boot conditions with a cold disk buffer
     cache for performance analysis. It does not affect anonymous memory that has been
     allocated through malloc, vm_allocate, etc.

SEE ALSO
     sync(8), malloc(3)

Dear GitHub: Please Improve Your Notifications

July 14, 2011

An Open Letter to GitHub

Dear GitHub,

Hi guys!

Guess what: GitHub’s great. Yeah, you know that.

But hey: could you please fix GitHub notifications? They seriously suck. No, really, I mean it. They’re the worst. Sorry, I don’t mean to hurt your feelings. I know a human being designed the notification system.

GitHub notifications are a productivity sink. Despite having fifteen checkboxes for customization in the Notification Center, I still can’t make them work in a way that helps me. Don’t get me wrong, I am not asking you to fix it by adding more checkboxes to the list. I am asking for an overhaul of how the notification system works. Below I will try to clearly lay out the problems I see and what I would like the system to do instead. The overall goal is to change notifications from a productivity sink to a productivity boon. (more…)

Best Presentations of RailsConf 2011

May 21, 2011

Hey all,

Yesterday evening I got back from RailsConf 2011. It was a lot of fun and I saw a lot of really good presentations with good technical content, and some that were both useful and funny (double dream hands and Ke$ha).

But I also missed some of the best talks. O’Reilly has posted some of the videos and is working on posting more.

But how to decide which ones to watch?

On the plane ride home I wrote a one-page site to answer that question. It scrapes the star ratings from O’Reilly (hope you guys don’t mind!) and shows the sessions with the highest-rated ones at the top. I didn’t have wifi so I had to guess what CSS selectors I should use to scrape the RailsConf site. Once I got home I fixed the selectors, polished it up, and pushed it to Heroku.

Here it is: the Best of RailsConf 2011.

If you find problems, please fork and improve it.

Hello, Entrepreneur. (And Consultant.)

March 8, 2011

The last time I changed jobs it was the spring of 1999, in the glory days of the dot-com frenzy. I decided to leave my job at an enterprise software company that shall remain unnamed (but it starts with “O” and ends with “racle.”) Enterprise software was not where my heart was. I thought about joining a startup and I talked to a bunch of them, but they all said the same thing when I asked about their business model: we’re not making any money but don’t worry, we’ve got millions of customers.

I knew we were in a bubble. Don’t get me wrong—I’m no soothsayer and I couldn’t tell you exactly when the bubble would burst, but it was clear it would. So I joined Intuit, the only company I interviewed with that was actually making a profit.

It turned out to be a pretty good choice.

The nearly 12 years I worked at Intuit were amazing. The QuickBooks team warmly welcomed me. I worked with fantastic people. I became the tech lead for the UI Toolkit team. I worked on a lot of elegant little touches that make the user experience more delightful, like a better quickfill (autocomplete) control. I trained engineers on how to build great user interfaces. I stayed there til 2005 when I decided to try something new, but Intuit is such a great place to work that I just transferred to another group. I moved around a couple more times, always staying in the Small Business Division, and since 2008 I have been doing web development in Intuit’s Grow Your Business division. This is the group that makes Intuit Websites.

I recently decided the time has come again to change jobs. But this time is different. Instead of looking for a job as an employee somewhere else, I’ve decided to do something I’ve been thinking about for a number of years: I am becoming a software entrepreneur and consultant/trainer.

Both? Well, yeah—I’ll be spending 30 hours a week consulting and training (focusing on Ruby on Rails and JavaScript) and the remaining time starting my own business.

My Startup

During my “entrepreneur” time I am creating a website with tools and community for small real estate investors. I am an investor myself, having bought houses and condos in Southern California, Arizona, and even Melbourne, Australia. When I got started with investing I was willing to invest anywhere in the U.S., but I had one big question:

Which market should I invest in?

The answer depended on what was I looking for in a real estate investment. Some investors look for equity growth, others for cash flow. Some look for a market on an upswing, others for a market in a trough. Some look for job growth, some for immigration, some for vacancy rates, and on and on. The thing is, all this data is available for free from the U.S. Government but it’s really hard for a small real estate investor to find. And once they’ve found it, it’s also hard to collate it and get a quick answer to the simple question of which market to invest in. Real estate agents can be helpful but unless you happen to find one who specializes in finding investing opportunities around the country, they won’t really know what to recommend. In that case they’re likely just to tell you that their own market is a good one to invest in.

So a few years ago I started working on a web app to solve this problem and recruited my friend Ed to help out. Think of it as Kayak for small real estate investors: you give it your criteria, drag some sliders, check some boxes, and it shows you the results. Except instead of showing you flights it shows markets. It’s fast and easy and you don’t need to pore through thousands of lines of data from government reports. The web app does all that for you instantly.

Working on the app was fun and we got a lot done over several months but it was hard to find enough time for that when we also had full-time jobs and families we wanted to see. But now that I’m consulting 30 hours a week instead working 40 hours a week, that leaves me more time every day. So I’m working on the app for real estate investors again.

I’ll make an announcement here when it’s ready to try. Subscribe to my blog so you don’t miss it. (Go here and click the Subscribe button in the right hand column.)

My Consulting and Training Business

To keep the lights on I am also doing Ruby on Rails consulting and training. I can make web apps work great on mobile phones and desktop browsers with a single code base, scale Rails apps, and a bunch more. See my About page if you’d like more info on my services, and my Contact page if you want to contact me about work.

I Like Stuff That’s Fun

I’m already having a ton of fun and I’ve barely started. It’s great to be working with Ruby on Rails full-time, controlling my destiny, and creating my future. And I’m really enjoying my first consulting gig.

Stay tuned.

ActiveRecord Now Supports an Identity Map. Hooray!

February 20, 2011

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

February 3, 2011

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).

January 22, 2011

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

January 17, 2011

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….

How to Lazily Find All Records in Rails 3 with Arel

October 30, 2010

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.

October 29, 2010

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.


Follow

Get every new post delivered to your Inbox.