Bill Sosin | Siong Chin

The Billion Dollar Gram | Information Is Beautiful

Billions spent on this. Billions spent on that. It’s all relative, right?

Muni platform, Embarcadero Station



<p>Muni platform, Embarcadero Station</p>

MySQL-Style Output for the Rails Console

While poking around the database in my rails console, I often found myself jumping to the mysql console just so I could get an easier-to-digest view of the data. I finally had enough of this silliness and wrote up a quick function to dump of set of ActiveRecord objects in the mysql report format.

>> report(records, :id, :amount, :created_at)
+------+-----------+--------------------------------+
| id   | amount    | created_at                     |
+------+-----------+--------------------------------+
| 8301 | $12.40    | Sat Feb 28 09:20:47 -0800 2009 |
| 6060 | $39.62    | Sun Feb 15 14:45:38 -0800 2009 |
| 6061 | $167.52   | Sun Feb 15 14:45:38 -0800 2009 |
| 6067 | $12.00    | Sun Feb 15 14:45:40 -0800 2009 |
| 6059 | $1,000.00 | Sun Feb 15 14:45:38 -0800 2009 |
+------+-----------+--------------------------------+
5 rows in set

Grab it from GitHub and stick it in your .irbrc.

Checking for STDIN in ruby

A colleague was asking today how he could see if there’s data waiting on STDIN in ruby (on Linux). On OS X, this is pretty straightforward:

if $stdin.stat.size > 0
  puts "got something: #{STDIN.read}"
else
  puts "nada"
end

That doesn’t work in Linux, though. After some digging, I found this post, which lead to:

require 'fcntl'

flags = STDIN.fcntl(Fcntl::F_GETFL, 0)
flags |= Fcntl::O_NONBLOCK
STDIN.fcntl(Fcntl::F_SETFL, flags)

begin
  puts "got something: #{STDIN.read}"
rescue Errno::EAGAIN
  puts "nada"
end

Which works on both platforms, but is (a) ugly (catching an exception), and (b) requires you to actually try to read from STDIN.

In playing around with that, though, I noticed that STDIN.fcntl(Fcntl::F_GETFL, 0) returned 0 if there was something on STDIN, and something non-zero (2 in OSX and 32770 in Linux) if STDIN was empty. So now the code is simple again:

require 'fcntl'

if STDIN.fcntl(Fcntl::F_GETFL, 0) == 0
  puts "got something: #{STDIN.read}"
else
  puts "nada"
end

I’m not sure how reliable that is on other platforms (it won’t work on Windows—fcntl is a Unix-y thing). If I’m understanding fcntl.h correctly, a return value of 2/32770 (0x8002) seems to indicate that the io stream in question is open for writing. I’m not sure if that is intended or just a side-effect. Anyone know?