Archive for the ‘Uncategorized’ Category

How to Make HTML5 Autofocus Work in IE

March 29, 2012

If you want to use HTML5′s autofocus attribute and make it work in all browsers, here’s an easy way to do it in one line of jQuery. This code will bail out and do nothing if the browser supports HTML5 autofocus.

$(function() {
  $('[autofocus]:not(:focus)').eq(0).focus();
}

How it Works

  1. [autofocus]: Find all attributes with the autofocus attribute…
  2. :not(:focus): …but not the ones that are already focused. This results in a list of length 0 in any HTML5-capable browser, so nothing more will happen.
  3. .eq(0): Get the first one since it doesn’t make sense to focus multiple elements.
  4. .focus(): Set focus to it.

Send a Page from Safari to Opera Mini When You Need to Reflow Text on the iPhone

March 25, 2012

You’re on your iPhone surfing the tweets and you come across a link to an article or discussion you want to read. You click it and start reading. But the text is too small so you two-finger zoom. But that makes the text too wide for the screen, even in landscape mode. And now you’re stuck feeling like a blooming idiot swiping your finger side to side down this long page while you try to read it. It distracts you from the thing you’re trying to read and it takes too long.

I Like Stuff That’s Not Horizontal Scrolling

The iPhone’s Safari browser can’t re-flow text in wide columns on web pages. For people like me, this is a deal-breaker. Scrolling side-to-side over and over again just to read a web page is time-consuming and annoying. It’s the primary reason I switched to Android a year and a half ago. Android’s browser fixes this problem exactly the way you would want: if you two-finger zoom into some text it immediately re-flows the text to fit the new screen size. I love it.

In iOS 5, Apple finally introduced Reader mode. A little “Reader” icon appears in the URL bar of some pages. Clicking it enlarges and reflows the text for better readability. It’s nice–when it works. Apple says “Reader in Safari smartly recognizes when there’s an article on the page,” but unfortunately it’s not as smart as they claim. There are plenty of pages where the text is too wide but the Reader icon doesn’t appear, so you’re still stuck scrolling side-to-side as you attempt to read.

For an example of a page that doesn’t re-flow nicely and doesn’t offer Reader mode, use your iPhone and try reading this discussion of Safari text re-flow on the Apple Support Communities site.

Opera Mini to the Rescue

There are other browsers that can claim they can reflow text on the iPhone. I’ve tried a bunch of them. The one I find does the best job of re-flowing text with minimal hassle on a wide variety of pages is Opera Mini, which is free and fast.

Here is the aforementioned discussion thread. The first picture is in Safari after zooming in to a readable font size. The second is Opera after doing the same. See the difference? In Safari you have to scroll side to side to read it. In Opera you don’t.

To enable text re-flow, go to Settings and turn on the “Text Wrapping” setting.

But Safari is the iPhone’s Default Browser

So that’s all well and good but what about that little story about surfing the twitterverse and clicking a link? Whenever you click a URL in any other app like email, Twitter, Facebook, etc., the iPhone will open the page in Safari. Apple doesn’t give you a choice. You can’t tell it to open in Opera. Sure, you could click in the URL, then long-click it, then choose Select All, then choose Copy, then launch Opera, then click the Opera URL bar, then click Paste. But by the end of all that it’s time to go to bed.

Well I just figured out a little workaround that costs nothing and lets you send any page from Safari to Opera in two clicks. So at any time you’re two clicks away from reflowing your text.

The trick is to use a bookmarklet I made called Send to Opera.

  1. First click: the Bookmark icon.
  2. Second click: the Send to Opera bookmarklet.

To add it, go to this Send to Opera page and follow the instructions.

How does it work? It simply inserts the letter “o” at the beginning of the URL. For example if the URL is http://ilikestuffblog.com/, Send to Opera tells the browser to open ohttp://ilikestuffblog.com/. With an O at the front, the request is sent to Opera.

Cool, huh?

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


Follow

Get every new post delivered to your Inbox.