Archive for the ‘Ruby’ category

Overcome Heroku’s “Permission denied publickey” problem

August 29, 2008

Heroku is awesome on paper (or screencast) but after following the directions it never worked for me. I couldn’t figure out why, and the Heroku discussion forum didn’t have any answers. But I think I’ve finally figured it out. (In the very least, I’ve finally gotten it working, which is the next best thing!)

Heroku (before today) would let me do everything except clone my remote apps to my local machine, which is more convenient, and in some cases essential (as when doing Rails apps with Hobo). Observe this:

$ heroku clone hobocookbook [/Data/Rails] [DrTeeth]
Initialized empty Git repository in /Data/Rails/hobocookbook/.git/
The authenticity of host ' (' can't be established.
RSA key fingerprint is 8b:48:5e:67:0e:c9:16:47:32:f2:87:0c:1f:c8:60:ad.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ',' (RSA) to the list of known hosts.
Permission denied (publickey).
fatal: The remote end hung up unexpectedly
/usr/local/lib/ruby/gems/1.8/gems/heroku-0.3/bin/../lib/heroku/command_line.rb:37:in `clone': could not clone the app. Is git installed? (RuntimeError)
from /usr/local/lib/ruby/gems/1.8/gems/heroku-0.3/bin/../lib/heroku/command_line.rb:6:in `send'
from /usr/local/lib/ruby/gems/1.8/gems/heroku-0.3/bin/../lib/heroku/command_line.rb:6:in `execute'
from /usr/local/lib/ruby/gems/1.8/gems/heroku-0.3/bin/heroku:36
from /usr/local/bin/heroku:19:in `load'
from /usr/local/bin/heroku:19

If I may cut to the chase…it appears that the Heroku setup process assumes that the public key you give it will be your default or only public key, while in fact I made a key pair just for Heroku. So once I added some details to my ~/.ssh/config file:

Port 22
IdentitiesOnly yes
IdentityFile ~/.ssh/id_heroku
TCPKeepAlive yes
User brandon

So far as I know, this solution isn’t listed anywhere else on the web, but I found a tiphere that mentioned changing your default public key, which tipped me off as to what the problem was. (Of course now that I know the solution, I could much more effectively Google to see if anyone else has found it–one of the shortcomings of current search technology as a strategy for finding answers. The keywords you really want to use are the ones in the answer, but of course you don’t know those until you know the answer.)

Anyway, I hope this helps the legions of other people out there who would love to use Heroku but can’t because their use case was overlooked by the set up program.


How to use Ruby in TextMate Snippets and Commands

July 25, 2008

Dr. Nic, one of our favorite Aussies (along with Ray Ozzy), posted a screencast on how to create TextMate snippets with Ruby embedded in them, as well as how to create commands with Ruby. Here’re the Cliff’s Notes versions of a snippet and command that will guess the class name you want to use based on the file name:

Snippet with Ruby

class ${1:`#!/usr/bin/env ruby
require 'rubygems'
require 'active_support'
puts ENV['TM_FILENAME'].gsub(/\.rb$/, '').camelize

Command with Ruby

#!/usr/bin/env ruby
require 'rubygems'
require "active_support"
puts <<-EOS
class ${1:#{ENV['TM_FILENAME'].gsub(/\.rb$/, '').camelize}}

He mapped these to “cla” in the bundle editor, but I recommend avoiding abbreviations. You’ll spend more time trying to remember how you abbreviated something than you’ll save by not typing two lousy characters.

The screencast’s volume is really low, so you’ll need to plug those external speakers into your laptop and crank the volume to what would normally be deafening levels just to hear him. The little tinny speakers on your MacBook won’t cut it this time.

Computers can’t even do math!?

May 15, 2008

Since the whole world by now should be aware of the general failure of artificial intelligence, it shouldn’t be very controversial to say that I’ve (mostly) always realized that computers can’t do many things that are very easy for people to do. Forget anything like thinking: the most basic identification of black shapes on a page as alphanumeric characters sometimes fails, and facial recognition seems to be a long way from being anywhere close to reliable.

But reading David Flanagan’s fabulous book “The Ruby Programming Language”, I discovered that computers can’t be trusted to do simple math either. Here’s the direct quote, followed by my simplified explanation.

Binary Floating-Point and Rounding Errors

Most computer hardware and most computer languages (including Ruby) approximate real numbers using a floating-point representation like Ruby’s Float class. For hardware efficiency, most floating-point representations are binary representations, which can exactly represent fractions like 1/2, 1/4, and 1/1024. Unfortunately, the fractions we use most commonly (especially when performing financial calculations) are 1/10, 1/100, 1/1000, and so on. Binary floating-point representations cannot exactly represent numbers as simple as 0.1.

Float objects have plenty of precision and can approximate 0.1 very well, but the fact that this number cannot be represented exactly leads to problems. Consider the following simple Ruby expression:

0.4 - 0.3 == 0.1 # Evaluates to false in most implementations

Because of rounding error, the difference between the approximations of 0.4 and 0.3 is not quite the same as the approximation of 0.1. This problem is not specific to Ruby: C, Java, JavaScript, and all languages that use IEEE-754 floating-point numbers suffer from it as well.

One solution to this problem is to use a decimal representation of real numbers rather than a binary representation. The BigDecimal class from Ruby’s standard library is one such representation. Arithmetic on BigDecimal objects is many times slower than arithmetic on Float values. It is fast enough for typical financial calculations, but not for scientific number crunching. Section 9.3.3 includes a short example of the use of the BigDecimal library.

So, in other words, if you ask what 0.4 – 0.3 is, you get the correct answer. But if you ask if 0.4 – 0.3 is equal to 0.1, you’re told that it’s not the same. And please remember: although Ruby is used in the example, this is not a bug in Ruby, but a generally accepted way for programming languages to work, which has been adopted by the international standards body IEEE.

Add to this the fact that different programming languages disagree what the remainder is when you divide a negative number by a postive number, and you’ll learn that you have to be very careful what you let computers do for you. They could even mess up the one thing that seems perfectly suited to them: basic math.

DRY initialization

April 4, 2008

Instead of writing this:

    def initialize(host, port, options = nil)
      @host = host;
      @port = port;
      @options = options;

wouldn’t it be nicer to be able to write something approximately like this:

    def initialize(host, port, options = nil)

or even better yet, simply this:

    initialize_variables(host, port, options = nil)

Hobo Cheatsheet, version 0.1

March 28, 2008

Here’s a (very! rough) Hobo cheatsheet, in PDF and HTML formats.

I’m not posting a Markdown version since it mangles source code, and is therefore only useful for natural language text.

Update: The PDF has been updated so that it’s easier to read. I accidentally put two pages of text on each page of the PDF, making it hard to read. I decided that, other than the font size, this was a good thing, so I just upped the font size and left it using a 2-page/sheet layout. Here it is.

The secret is out!

March 21, 2008

For all the millions of people reading my blog, I have a secret to share: the much-anticipated changes in Hobo, that were promised for the end of the month, are now mostly available in Hobo version 0.7.3.

Okay, okay, they didn’t really promise it, but publicly set that as a goal.

And okay, okay, it’s not really a secret—they posted it on their web site, but only in the forums, so only the dedicated few would find it.

And while you’re pinning me down with technicalities, there might not be quite a million…


March 12, 2008

While reading something of why’s on meta-programming, and looking at some of his example code

class MailTruck
  attr_accessor :driver, :route
  def initialize( driver, route )
    @driver, @route = driver, route

I thought to myself “why don’t we have something as DRY as attr_accessor for meta-programming the initialize method? Why not something like

class MailTruck
  attr_accessor :driver, :route
  initializer :driver, :route 

In other words, why write “driver, route” three times?

A project for a rainy day…