Announcing: the first professional Docker training by a third party

November 4, 2013

You might have heard about Docker, the new open source project that lets you pack, ship and run any Linux application as a lightweight container. It has been getting a lot of attention since dotCloud (now renamed Docker, Inc.) open-sourced it in March.

If you’ve been curious about it and you learn best by doing, check out the new 3-hour Hands on with Docker introductory class that I will be teaching with Alvin Lai on Tuesday, November 12th, 2013 (that’s next week). We are excited to offer the first professional Docker training by any third party.

This is a beta class, so all we are charging is $50 to cover basic expenses (meeting room rental, pizza, etc.). We won’t make a profit on the beta class. When we start teaching the finalized class, it will cost several hundred dollars. So now is your only chance to save money and take the class for only $50.

I could write a lot more, but all the deets are on the Hands on with Docker page.

I hope to see you in class on Nov 12th. Any questions? My email is on that page.

Hey, Google. You Know that New Floating Facility You’re Building in the Bay? Please Name it Floating Point.

October 29, 2013

About four days ago, news broke that Google is building some large floating structure in the San Francisco Bay. According to CNET, “It is located on a barge just off Treasure Island, between San Francisco and Oakland.”

There has been a lot of speculation about what it is. A floating data center? A mobile retail store for selling Google Glass? A water-borne launch pad for giant Internet wifi blimps?

Whatever you’re building in the Bay, Google, I have only one request:

Please name it Floating Point.

Clearly that is the only name you could give this structure.

Apple has Infinite Loop. You can’t let them be the only Silicon Valley company with a clever name. You need something just as good. Now’s your chance.

Name it Floating Point. Please.

Readers, tweet this if you agree.

Google Structure

Do you Want Someone to Impersonate You to Your LinkedIn Contacts and Leave You Humiliated? Try FounderDating.

April 26, 2013

[Edit: FounderDating's CEO, Jessica Alter, politely asked me to remove the word "spam" from the title of this post because that word implies I didn't know a message would be sent out. I have changed the post's title at her request.]

A week ago, a friend of mine asked me to write a recommendation for him on FounderDating.com. I happily complied, and when I was done writing the recommendation I was shown pictures of a bunch of my LinkedIn contacts. FounderDating asked me to identify ten that I would vouch for. I didn’t have to do it but I thought oh well, I guess I’ll do it and see what happens. So all I did was click their photos. Nothing more. [Edit: after clicking their photos I clicked a button to submit my selections.]

Bad idea.

As far as I could tell, nothing happened. I figured behind the scenes maybe they would send notes to these people, telling them their contact Brian Morearty had used FounderDating, and suggesting that they try it too. I understand social networking and I understand that when you give an app permission to access a social networking account, your contacts will see that you used it. That would have been ok with me. But what they did was more insidious than that.

FounderDating used the LinkedIn API to send the following note to these ten contacts. I don’t remember being asked to approve the wording–because if I had been asked, I most certainly would not have approved the wording. [Edit: there actually was a link to "see/edit this message" at the bottom left of the form. I apparently didn't see it because it was in the smallest font size on the form and wasn't underlined, the way links often are. If I had clicked it I would have had a chance to change the text of the outgoing message.] I was humiliated this morning when one of my contacts sent me a heartfelt thank-you. I had to write back that while I most definitely do believe in him, I did not write this note.

Here’s what FounderDating wrote to the ten LinkedIn contacts I identified:

Hey [Name],

I was asked to vouch for a few people to join FounderDating – an invite-only network of entrepreneurs (50% engineers) all ready to start their next side-project or company. You’re on my short list. I highly recommend applying.

Apply here > [url]

(Note: copy and paste this link if it’s not clickable).

You can thank me later,
Brian

It seems factually correct, right? Let’s break it down:

  • “Hey [Name]:” personal greeting. Implies that I wrote it myself, not that it was written by someone else to my contacts.
  • “I was asked to vouch for a few people to join FounderDating:” this is accurate. However, again, it implies I wrote this note myself.
  • “You’re on my short list:” well, yes, they did ask me for ten of my contacts. But this gets embarrassingly personal at this point. I highly respect all ten of the people whose photos I clicked. But several of them are people I would not say to their face, “you’re on my short list.”
  • “I highly recommend applying:” EXCUSE ME? When did I recommend applying, much less HIGHLY recommend it?
  • “You can thank me later.” OH MY GOD. What kind of ass says that when he recommends signing up for some online service?

For fuck’s sake, at this point I most certainly DO NOT recommend people use FounderDating. Quite the contrary. I have shut them off from sending more messages on LinkedIn.

Sorry for the rant. I fell for a scam and I’m embarrassed. I hope you will learn from my mistake.

I have written to LinkedIn’s support team notifying them of this abuse of their API Terms of Service. See Section D: “Don’t Harm or Trick Members.”

Your Application must not:

  • Impersonate a LinkedIn user or misrepresent any user or other third party when requesting or publishing information.

Follow-up

On May 8, 2013, this post made the front page of Hacker News and got a lot of attention. FounderDating’s CEO, Jessica Alter, contacted me and we exchanged several emails. She was polite. She requested that I make some corrections to this post, which I have done. Specifically:

  • I added a comment saying that after selecting the pictures of my LinkedIn contacts, I clicked a button to submit the form.
  • I removed the word “spam” from the post’s title because that word “implies we don’t let you know a message goes out.” They did let me know a message would go out. (See screenshot below.) And even if they hadn’t let me know that, I mentioned in the post that I did expect a message to go out.
  • I clarified that there actually was a “see/edit this message” link in the bottom left hand side of the form. I didn’t notice this link because it was in small type and it looked exactly like the text above it, which was not a link.

Here is a screen shot of the form (I blurred the names):

FD form blurred

If you click “See/edit this message” in the bottom left corner, this is what you see:

FD wording

To reiterate, all FounderDating did was send a message I didn’t like to a few people I chose. In addition to requesting that I make clarifications to this post, Ms. Alter asked me what changes I would like to see made to the UI on FounderDating. I requested that they show me the flip-side of the lightbox before the messages get sent, without requiring me to choose to “see/edit” the message. Something like a 2-step wizard would be fine. Step 1: select contacts. Step 2: I am presented with the second screenshot.

I would also like the default message to be less annoying.

Establishing a Connection to a Non-Default Database in Rails 3.2

September 21, 2012

If you’ve ever built a Rails app in which some models don’t connect to the default database, you know that establish_connection is the method you would call make the connection.

But before I get to that: the space shuttle Endeavor flew directly over my street today, low and slow, with a fighter jet escort. My neighbors and I had an amazing view of it. It was piggybacked on a 747 transport for a publicity tour across California before being retired at a Southern California museum. It was exciting!

Shuttle Flyover

So. Let’s say you needed to talk to an external NASA database. You would create new keys in database.yml called nasa_development, nasa_test, and nasa_production:

# database.yml
development:
  # development configuration goes here

nasa_development:
  # development configuration to external database goes here

# same for test and production...

Then define your models like this:

class Astronaut < ActiveRecord::Base
  establish_connection "nasa_#{Rails.env}"
end

In this example, Rails looks for an ‘astronauts‘ table in the external database. (Automatic table naming still works. You can override that too, by calling self.table_name=).

In the past, when I’ve had multiple tables on a single connection, I always included a module that makes the connection. Let’s define models for Astronaut and Shuttle:

module NasaConnection
  extend ActiveSupport::Concern
  included do
    establish_connection "nasa_#{Rails.env}"
  end
end

class Astronaut < ActiveRecord::Base
  include NasaConnection
end

class Shuttle < ActiveRecord::Base
  include NasaConnection
end

That might have been overkill. I could just as well have done this:

class Astronaut < ActiveRecord::Base
  establish_connection "nasa_#{Rails.env}"
end

class Shuttle < ActiveRecord::Base
  establish_connection "nasa_#{Rails.env}"
end

In both of these techniques, establish_connection is called twice. This works in Rails 3.1.8 and earlier, but starting in 3.2.0 you will get runtime errors. An example:

class Astronaut < ActiveRecord::Base
  establish_connection "nasa_#{Rails.env}"
  has_many :missions
  has_many :shuttles, through: :missions
end

class Shuttle < ActiveRecord::Base
  establish_connection "nasa_#{Rails.env}"
  has_many :missions
  has_many :astronauts, through: :missions
end

class Mission < ActiveRecord::Base
  establish_connection "nasa_#{Rails.env}"
  belongs_to :astronaut
  belongs_to :shuttle
end

# test
shuttle = Shuttle.create name: "Endeavor"
shuttle.astronauts << Astronaut.create(name: "Mark Kelly")
assert_equal 1, shuttle.reload.astronauts.count # FAIL

Different database adapters will give you different errors. (I tried SQLite and Postgresql.) The problem is in ActiveRecord, not in the adapters.

Trying to Find a Fix

The fact that this doesn’t work any more seems to me like a bug in ActiveRecord. So I used a debugger to step through the establish_connection code in Rails 3.1.8 and 3.2.8, trying to identify the problem. I found a comment above the definition of the ConnectionHandler class that gave me a hint:

# suppose that you have 5 models, with the following hierarchy:
#
# |
# +-- Book
# | |
# | +-- ScaryBook
# | +-- GoodBook
# +-- Author
# +-- BankAccount
#
# Suppose that Book is to connect to a separate database (i.e.
# one other than the default database). Then Book, ScaryBook
# and GoodBook will all use the same connection pool. Likewise,
# Author and BankAccount will use the same connection pool.
# However, the connection pool used by Author/BankAccount
# is not the same as the one used by Book/ScaryBook/GoodBook.

Ah! So maybe ActiveRecord requires you to create a common base class for all models that will talk to the same external database. So I tried it. Notice that Astronaut, Shuttle, and Mission are all subclasses of NasaTable, which is a subclass of ActiveRecord::Base:

class NasaTable < ActiveRecord::Base
  establish_connection "nasa_#{Rails.env}"
end

class Astronaut < NasaTable
  has_many :missions
  has_many :shuttles, through: :missions
end

class Shuttle < NasaTable
  has_many :missions
  has_many :astronauts, through: :missions
end

class Mission < NasaTable
  belongs_to :astronaut
  belongs_to :shuttle
end

# test
shuttle = Shuttle.create name: "Endeavor"
shuttle.astronauts << Astronaut.create(name: "Mark Kelly")
assert_equal 1, shuttle.reload.astronauts.count

This code, like my earlier code, worked great in Rails 3.1. But it still failed in Rails 3.2, only now for a different reason: ActiveRecord tried to connect to a table called ‘nasa_tables‘. I thought it must be associating all three subclasses with that table.

Hmm, easy but annoying to fix, right? Force Rails to use the right table names:

class Astronaut < NasaTable
  self.table_name = 'astronauts'
  ...
end

class Shuttle < NasaTable
  self.table_name = 'shuttles'
  ...
end

class Mission < NasaTable
  self.table_name = 'missions'
  ...
end

Nope, that still didn’t work. Rails was still looking for the nonexistent ‘nasa_tables‘ table. Looks like self.table_name= is not going to solve this particular problem.

MoonEventually I found a discussion of a Rails issue where someone was having this problem. In their example, A was the base class and B was the subclass. @tenderlove said, “Out of curiosity, why would you do this? If there is no A table, you should set the class to be abstract.”

Abstract? I know how to define abstract classes in other languages like C++ but I’ve never heard of an abstract class in Ruby. Well, it turns out he’s talking about an ActiveRecord concept, not a Ruby concept. Any subclass of ActiveRecord can declare itself abstract by setting self.abstract_class = true. This tells ActiveRecord that it shouldn’t look for a table to go with that class.

I Like Stuff that Finally Works

Armed with this information I finally landed on a solution that works in Rails 3.2. As you can see, 3.2 is much less flexible than 3.1 about how you define your class structure to talk to external databases. Whereas 3.1 had several techniques that would work, as far as I know the following is the only way to make it work in 3.2:

  1. Make a common base class for all models that need to talk to a non-default database.
  2. Tell ActiveRecord that this base class is abstract.
  3. Establish the connection in the base class.

So here’s our final code:

class NasaTable < ActiveRecord::Base
  self.abstract_class = true
  establish_connection "nasa_#{Rails.env}"
end

class Astronaut < NasaTable
  has_many :missions
  has_many :shuttles, through: :missions
end

class Shuttle < NasaTable
  has_many :missions
  has_many :astronauts, through: :missions
end

class Mission < NasaTable
  belongs_to :astronaut
  belongs_to :shuttle
end

# test
shuttle = Shuttle.create name: "Endeavor"
shuttle.astronauts << Astronaut.create(name: "Mark Kelly")
assert_equal 1, shuttle.reload.astronauts.count # IT WORKS

A Side Note About Connection Pools

It would be nice to have the flexibility that 3.1 had. But as long as there is a reasonable solution, I’m happy. I should mention, however, that if you call establish_connection multiple times with the same connection key (e.g. the old way where each table calls establish_connection), you end up creating multiple connection pools to the same database. This seems like a problem, as Sam Saffron has pointed out. If a single app talks to a single database through multiple connections, the best way to manage those connections is via a single pool–not multiple pools that don’t know about each other.

If you stick with the method I described above, where only one base class establishes a connection to each database, you can avoid this problem.

Astronaut

You Should Update One Gem at a Time with Bundler. Here’s How.

July 1, 2012

[Update: added example of updating the sextant gem, which causes Rails to be updated as well.]

Hey Ruby developers,

When you run bundle update to update your gems, it updates all of them at once. If your app stops working or your tests start failing, it can be pretty hard to figure out which gem update broke it.

There are a couple of solutions I’ve seen people use to solve this. Neither of them is that great:

  1. Lock the versions numbers in your Gemfile. But hey, that’s a pain and it’s what Gemfile.lock is for. Locking the version numbers in the Gemfile should be the exception, not the rule.
  2. Run bundle update gemname.

You might think bundle update gemname would just update that gem. But no, it also updates the gem’s dependencies—whether they have to be updated or not.  In fact, updating a third party gem can even upgrade you to a new version of Rails behind your back.

Here’s what the Bundler doc says about bundle update gemname:

UPDATING A LIST OF GEMS

Sometimes, you want to update a single gem in the Gemfile(5), and leave the rest of the gems that you specified locked to the versions in the Gemfile.lock.

For instance, in the scenario above, imagine that nokogiri releases version 1.4.4, and you want to update it without updating Rails and all of its dependencies. To do this, run bundle update nokogiri.

Bundler will update nokogiri and any of its dependencies, but leave alone Rails and its dependencies.

Yeah, sure, that sounds nice. But read that last sentence again: “Bundler will update nokogiri and any of its dependencies.” Well, heck. Some gems depend on a ton of other gems. And why not? Nothing wrong with that. And it makes sense to update the dependencies if something new is required for the update to work. But Bundler updates them no matter what. And now you’re back to the problem I stated at the beginning: even if you intend to update only a single gem, you still end up updating a whole boatload of gems. So when your app breaks or your tests fail, it takes a lot of time to figure out why.

Want an example of an unexpected side-effect of bundle update? I have a good one. Let’s say you’ve installed the sextant gem into your Rails app so you can see your Rails routes in development mode by navigating to /rails/routes. (It saves time compared to rake routes since the environment is already loaded.) In this example you are on Rails 3.2.2 and sextant 0.1.2. Now you run bundle update sextant to update to 0.1.3. Do you know what you just did? You upgraded Rails from 3.2.2 to 3.2.6. I don’t know about you, but I don’t like having my version of Rails updated just because I got the latest version of some little helpful gem.

When writing this blog post I tried a few scenarios. I found something else interesting:

With bundle update gemnameeven if there is no newer version of that gem, it will still update everything the gem depends on.

Here’s an example. My app has version 0.3.4 of haml-rails, which at the moment is the newest version. I run:

bundle update haml-rails

After that, git diff informs me that my Gemfile.lock now has newer versions of the journey, json, multi_json, and sprockets gems. Even though it didn’t find an update to haml-rails.

The Solution: bundle update ––source gemname

Bundler has a solution, but in my opinion it’s hard to understand the documentation.

Here’s what you do:

bundle update ––source gemname

I started diving into Bundler’s code and specs to see exactly what this does but it was taking more time than I wanted to spend. But I’ve been using this for more than a year and it works great. I recommend this be your default way to update a gem. If it doesn’t work due to a dependency conflict with other gems then you can always fall back on bundle update gemname.

As far as I can tell, using ––source is the equivalent of the following, but without all the work and headache:

  1. Specifying version numbers for everything in your Gemfile.
  2. When you want to update a gem, running gem list -r gemname to find out its latest version number.
  3. Changing the version number in your Gemfile for just that one gem.
  4. Running bundle install.
If you look at bundle update‘s documentation for ––source, it doesn’t help much. Here’s what it says:

OPTIONS

––source=<name>

The name of a :git or :path source used in the Gemfile(5). For instance, with a :git source of http://github.com/rails/rails.git, you would call bundle update ––source rails

By the way, the bundle update documentation does mention conservatively updating dependencies. Here is what it has to say: “For more information, see the CONSERVATIVE UPDATING section of bundle install(1) bundle-install.1.html.” The bundle install section on conservative updating does indeed describe how to update dependencies conservatively. However, this section assumes you are specifying version numbers in your Gemfile. As I mentioned above, I prefer to do that only as an exception.

See ya.

How to Find a Record in ActiveRecord Using either an ID Or an Object

June 12, 2012

Have you ever written written code in an ActiveRecord model where you wanted the caller to be able to pass in either an object or an id?

In this example you want to know if a user has read a post. Your join table, readings, tells you which users have read each post.

class Post
  has_many :readings

  def read_by?(user_or_id)
    readings.where(:id =>
                     Fixnum === user_or_id ?
                     user_or_id :
                     user_or_id.id).exists?
  end
end

Good news: you don’t have to go through all that. ActiveRecord checks for you if the object is a number or a model. You can simplify the code quite a bit.

In this rewritten version the user parameter of the read_by? method can be either a user object or a user id:

class Post
  has_many :readings

  def read_by?(user)
    readings.where(:id => user).exists?
  end
end

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?

19-Minute Video: CoffeeScript for Rubyists

January 11, 2012

If you’re a Ruby programmer and want a quick little intro to CoffeeScript so you can decide whether you might want to use it, check out the 19-minute talk I gave last week at a really fun Code Social meetup at RocketSpace in San Francisco. The talk was “CoffeeScript for Rubyists.”

Abstract

Is CoffeeScript really so great? Why use it instead of good ol’ JavaScript? Which of my favorite syntax goodies does it steal from Ruby? It looks Pythony with all that significant whitespace. How can I use it in my pre-3.1 Rails project? How do I convert my legacy JavaScript? Why is Internet Explorer no good at exploring the Internet? Brian Morearty answers most of these questions. He’s a Ruby aficionado who has used CoffeeScript for his client-side coding for a few months. In this talk he does a quick demo of how to install CoffeeScript, convert your JavaScript to CoffeeScript, and include it in a pre-Rails-3.1 application. But most of the talk is on details of the language, including stuff it stole from Ruby that make it just dang fun for a Rubyist to program in CoffeeScript. And he even covers one thing that is *gasp* better than Ruby.

Slides

Here are the slides for this CoffeeScript talk.

Video

And here’s the video:

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)

Follow

Get every new post delivered to your Inbox.