jemnotesversion 2 / featuring ruby or see all/search

May 18
This little fragment extends the ruby string class to check that all round, square and curly brackets occur in appropriate couplings.
class String
  def brackets_match?
    stack = []
    each_char do |c|
      case c
      when '(', '[', '{'
        stack << c
      when ')'
        return false unless stack.pop == '('
      when '}'
        return false unless stack.pop == '{'
      when ']'
        return false unless stack.pop == '['
      end
    end
    stack.empty?
  end
end
and the tests:
should 'test matching brackets' do
  assert '(this)'.brackets_match?
  assert '(this)(fine)'.brackets_match?
  assert '(this)(fine)'.brackets_match?
  assert '[this][fine]'.brackets_match?
  assert '(this){fine}'.brackets_match?
  assert '(thi(s)){fine}'.brackets_match?

  refute '(thi(s)((fine)'.brackets_match?
  refute '{this){fine}'.brackets_match?
  refute '{this)(fine}'.brackets_match?
  refute '{this)(fine}'.brackets_match?
end
Mar 29
From the simple and obvious, yet extremely useful department: add
$DEBUG = true
to the front of your code, and threads will abort on exceptions, yielding the useful error trace. Details here.
Mar 28
Perhaps || should always be used in Ruby in preference to or—I thought it was less attractive than or to look at, but check this out:
puts false or true   # interpreted as puts(false) or true
=> false
puts false || true   # interpreted as puts(false || true)
=> true
I knew that the precedence for or was low in Ruby, but I didn’t realise it was this low.
Mar 27
A good article here about the difference between alias and alias_method in ruby. It suggests:
alias_method :new_name, :old_name
in preference to
alias new_name old_name
Not sure I agree which is better, but at least this makes the differences clear.
Mar 19
This page summarizes ‘ruby-debug’, which looks like a nice useful gem. I particularly like this line:
(rdb:1) b app/controllers/my_controller.rb:10
Feb 24
To retrieve a list of files matching a certain pattern, and/or in a certain directory, use Dir.glob.
Two examples:
Dir.glob 'dir/*'
Dir.glob 'dir/*.rb'
Feb 21
Call it the principal of least surprise, or don’t, but so often in Ruby what I hope is the case, actually is the case. Among many examples I’ve found today alone, take the word super. This calls a method of the same name, using the implementation next up the class hierachy. This is as expected. You can pass arguments to super if you like, as expected.
And, as hoped, if you call it without arguments, it will pass the original method’s parameters. Nice.
Jan 25
The chronic gem looks great, as a way of parsing natural language dates. Here are their examples, lifted straight from the above website. Would be interesting to build this into a website.
require 'chronic'

Time.now   #=> Sun Aug 27 23:18:25 PDT 2006

Chronic.parse('tomorrow')
  #=> Mon Aug 28 12:00:00 PDT 2006

Chronic.parse('monday', :context => :past)
  #=> Mon Aug 21 12:00:00 PDT 2006

Chronic.parse('this tuesday 5:00')
  #=> Tue Aug 29 17:00:00 PDT 2006

Chronic.parse('this tuesday 5:00', :ambiguous_time_range => :none)
  #=> Tue Aug 29 05:00:00 PDT 2006

Chronic.parse('may 27th', :now => Time.local(2000, 1, 1))
  #=> Sat May 27 12:00:00 PDT 2000

Chronic.parse('may 27th', :guess => false)
  #=> Sun May 27 00:00:00 PDT 2007..Mon May 28 00:00:00 PDT 2007
Jan 12
The geokit gem for ruby is extremely good. Within seconds of installing it I could use it to look up locations and distances. Now to apply this to analyzing tracks made by runkeeper, exported to gpx format, processed with hpricot, and bound together with much ruby goodness.
Jan 12
I’ve had some trouble getting the jemnotes server running in the background. I’m going to try using the daemons gem. It looks excellent.
Update: I immediately got things working exactly the way you’d expect. This is a great gem. I haven’t yet got the logging working, though.
Dec 15
Here’s how to create a directory, if it doesn’t already exist. This works to an arbitrary depth—perfect for creating a whole hierachy straight away.
FileUtils.mkdir_p '/tmp/a/b/c/d/e/'
Apparently, it receives a list, too. Details here.
Dec 15
It seems Ruby rounds inconsistently—when told to display to 1 or 2 significant figures, it rounds 5s to 1 and 2, respectively—instead of being the same. Not sure why!
>> [1.14, 1.15, 1.16].map{|x| "%.1f" % x}
=> ["1.1", "1.1", "1.2"]
>> [1.4, 1.5, 1.6].map{|x| "%.0f" % x}
=> ["1", "2", "2"]
Edit: Nope, not a bug. This is because 1.15 gets translated to an internal, imprecise float which is slightly less than 1.15. I thought I understood most of the implications of floating-point imprecision—apparently not.
Dec 12
To find where a particular ruby gem lives, use this:
> gem1.9 which haml
(checking gem haml-2.2.15 for haml)
/usr/local/lib/ruby1.9/gems/1.9.1/gems/haml-2.2.15/lib/haml.rb
Dec 10
Another reason I love ruby: say I have an array of items (a ‘list’, in python) and want to convert it to a hash (python: ‘dictionary’) giving the frequency of each item. I can do it like this:
def freq_table(a)
  d = {}
  d.default = 0
  a.each{|x| d[x] += 1}
  d
end
(Yep, that’s all you need!)
Dec 10
Here’s a nice patch to the string class in Ruby to test if a string represents a valid floating-point number:
class String
  def valid_float?
    true if Float self rescue false
  end
end
Dec 9
I saw artist Candice Breitz’ video installation of 30 fans singing along to a Madonna album in the Boston Museum of Fine Arts Seeing Songs exhibition. I mentioned it to some friends, and we ended up trying it ourselves. We first, all together, sang a song and recorded the sound. Then, one at a time, we videoed each other singing the music while listening to the group track with headphones. That gave us 9 videos that we wanted to tile in a 3x3 grid, synchronize, then convert to one video.
I started off using iMovie, but the interface was laggy and inconsistent as my computer struggled with the load. You can also only play two videos simultaneously, using the picture-in-picture feature. You’d have to add one video at a time, and constantly export and re-import. This wasn’t going to work.
Then I discovered rmov, an excellent library for opening, editing and exporting QuickTime movies within Ruby. It worked spectacularly well, and I made the video as desired. I found the required start-time offsets to synchronize the streams by importing streams one by one and comparing them to a single person; then I could just compose all the streams together. I often just exported the audio, which made it much faster to render while deciding on the offsets.
Lastly, here’s the code I used.
require 'rubygems'
require 'rmov'

# locs refers to the filename of the original files.
locs = [2732, 2734, 2736, 2739, 2740, 2744, 2746, 2748, 2749]
offsets = [41.12, 4.25, 1.8, 0.0, 0.8, 2.5, 1.65, 4.7, 0.8]

clips = []
locs.zip(offsets).each do |l,off|
  filename = "source/MVI_#{l}/MVI_#{l} - iPhone.m4v"
  clips << QuickTime::Movie.open(filename)
  clips.last.delete_section 0, off
end

background = QuickTime::Movie.open 'source/background_480x360.png'

q = QuickTime::Movie.empty
length = clips.map(&:duration).max.ceil
puts length
(length*15).times do
  q.insert_movie background, 0
end

WIDTH = 480
HEIGHT = 360

clips.each_with_index do |c,i|
  row = i / 3
  col = i % 3

  q.composite_movie c, 0

  a = q.tracks[-1]
  a.scale 0.34, 0.34
  a.translate col*WIDTH/3, row*HEIGHT/3
end

exporter = q.exporter
if File.exist? 'settings.st'
  exporter.load_settings 'settings.st'
else
  exporter.open_settings_dialog
  exporter.save_settings 'settings.st'
end

outname = "output.mov"
puts "creating #{outname}."
exporter.export outname do |progress|
  percent = (progress*100).round
  puts "#{percent}% complete"
end
Dec 6
Here’s how to open a server at the next available port, then retrieve the port number:
server = TCPServer.new '127.0.0.1', 0
port = server.addr[1]
Dec 3
Unusual branding, but these folks have some nice tools. I’ve used heckle before, but flog and flay look good, too.
  • heckle modifies your code, making sure code modifications break at least one test.
  • flog analyzes your code, showing you how hard it is to test.
  • flay tries to find code that looks similar to other bits of code, reporting code that is a good candidate for refactoring.
Nov 28
I couldn’t get script/console to load the right version of Ruby. Turns out you can use
script/console --irb=irb1.9
Oct 29
Some more details about using rake.
And this page talks about some options when you want the output folder to be different to the input.
Oct 20
The special DATA variable in Ruby is kind of interesting. It lets you easily parse multiple input files as one.
Oct 20
Ruby 1.9 has some nice new methods on the Enumerable class; for example, each_cons, which iterates through consecutive slices of an array. You can add these to Ruby 1.8 with
require 'enumerator'
Oct 15
Surely rakefiles are the future. GNU Make just looks antiquated.
Update: not so sure. Rake seems like it’s not that great after all. I might try writing my own sometime.
Oct 15
Oct 6
Oct 4
Install a good fork of rcov, which works without the dependency on REXML.
gem install relevance-rcov --source http://gems.github.com
Sep 23
Tioga is ‘plotting using Ruby, PDF, and TeX’. It looks pretty good.
Aug 5
A nice introduction to ragel with ruby.
Aug 5
Taking things to extremes when calculating the product of 1 through to 9.
# Python version.
prod = 1
for x in range(1, 10):
    prod *= x
prod
# Ruby version.
(1..9).inject :*
Aug 5
Mostly from the pickaxe book.
  • Compare array[start, length] and array[start..end].
  • x.freeze prevents modification to x.
  • books.first, but also books.first(3).
  • File.open(filename).each_with_index do |line, index|.
Aug 5
From the pickaxe book.
Create an enumerator object: e = (1..10).to_enum, or e = (1..10).each (without a block). Then, x = e.next. to_enum and enum_for are the same.
Or, create multiple, and use a loop to figure out the details (and throw a StopIteration when any of the iterators run out of elements).
x = ('a'..'z').to_enum
y = (1..10).to_enum
loop do
  puts "#{x.next}: #{y.next}"
end
Can also use with_index on an enumerator to convert it back for use with a code block. Or call a method for each element of the iterator, then convert it to an array: (1..10).to_enum(:each_slice, 3).to_a.
Aug 3
After gem installing wirble, add these lines to your ~/.irbrc to get syntax colouring etc. Courtesy of pablotron.
begin
  # Load wirble
  require 'rubygems'
  require 'wirble'

  # Start wirble (with color)
  Wirble.init
  Wirble.colorize
rescue LoadError => err
  warn "Couldn't load Wirble: #{err}"
end
Jul 30
Short, simple and sweet. Found here, which reports that it’s attributable to Sam Stephenson.
IO.read('image.png')[0x10..0x18].unpack('NN')
Jul 28
A good summary of ruby operators.
Jul 28
An explanation of Ruby’s percent syntax. Example:
# Same as ['symmetric', 'matrix', 'vector', 'scalar']:
%w{symmetric matrix vector scalar}
Jul 22
Interactive Ruby terminal via ajax. Very well implemented.
Jul 21
Ruby has a conditional assignment operator: ||=. This will assign to a if a is nil (ie, not initialized).
Mar 31
Ruby has an unless statement equivalent to if not. Nice. And the RailsTips blog has some good suggestions on usage.