Hi, I'm Samuel Cochran

on Tumblr, Google, Twitter, Facebook, LinkedIn, Flickr, GitHub, Launchpad, Stack Overflow and Xbox Live.

Thursday, November 3rd, 2011

Predictable Random Elements from ActiveRecord

Say you want to get some random examples to display, but you want those examples to be the same for each user. Ruby doesn’t really make it easy to seed a random number generator, so instead we can use a hash digest:

Digest::MD5.hexdigest("bob@example.com")
=> "4b9bb80620f03eb3719e0a061c14283d"

This gives a predictably unique(ish) result for each unique input, so each user’s email or username should be sufficient. The hex representation isn’t all that useful though. If we can generate full bytes then we can chop off some bytes as unsigned numbers…

Digest::MD5.digest("bob@example.com")
=> "K\x9B\xB8\x06 \xF0>\xB3q\x9E\n\x06\x1C\x14(="

Cool! Let’s run the unpack method over this bad boy:

Digest::MD5.digest("bob@example.com").unpack "C*"
=> [75, 155, 184, 6, 32, 240, 62, 179, 113, 158, 10, 6, 28, 20, 40, 61]

We get some few 8-bit unsigned integers. If 255 isn’t big enough for you, you can grab 16, 32 or even 64-bit unsigned integers instead, but we’ll get fewer:

Digest::MD5.digest("bob@example.com").unpack "Q*"
=> [12916024801687542603, 4406794345975029361]

Now we have some numbers we can seed a new random number generator:

random = Random.new Digest::MD5.digest("bob@example.com").unpack("Q").first
=> #<Random:0x007fed619e5060>
random.rand
=> 0.1594236871887449
random.rand
=> 0.03664397704408895

This will always produce the same sequence of random numbers.

If you want to instead just shuffle an array of items, try:

random = Random.new Digest::MD5.digest("bob@example.com").unpack("Q").first
=> #<Random:0x007fed619e5060>
["one", "two", "three"].sort_by { random.rand }
=> ["two", "one", "three"]

There are probably different and better ways to do this, but this way works for me!

Monday, October 31st, 2011

Ruby 1.9.3 p0 ruby-debug with RVM (easy version)

If you just want to use 1.9.3 p0 with ruby-debug on RVM, here’s one I prepared earlier (thanks to @ed_ruder):

$ curl https://github.com/sj26/ruby-1.9.3-p0/compare/ruby_1_9_3_0...master.diff > /tmp/ruby-1.9.3-visibility.diff
$ rvm install 1.9.3-p0 --patch /tmp/ruby-1.9.3-visibility.diff
$ rvm use 1.9.3-p0
$ gem install ruby-debug19

The full explanation is in my previous post.

Monday, October 31st, 2011

Updated: Using ruby-debug on Ruby 1.9.3 p0

This is an updated re-post of Using ruby-debug on Ruby 1.9.3 preview1 updated for Ruby 1.9.3 p0 (release, patch level 0).

Ruby 1.9.3 has a slightly broken build process. In the final step of compilation it hides a number of symbols while linking the ruby binary. This means ruby-debug’s extension can’t get all the information it needs to make the debugger work and it breaks.

To fix, first grab some coffee, tenderlove-style.

You need to recompile after removing a line from configure.in. Make sure you’ve got a copy of the ruby 1.9.3 source then apply this patch:

$ git apply <( curl https://github.com/ruby/ruby/pull/56.diff )

Recompile, making sure you run autoconf (I don’t think RVM does by default):

$ autoconf -f && ./configure --prefix="$HOME/.rbenv/versions/1.9.3-p0" && make -j3

Double check it’s worked by checking the _ruby_current_thread symbol is visible (or you can just trust me):

$ nm ruby | grep current_thread
00000001002249d0 D _ruby_current_thread

Then install as normal (make install), set up rubygems, gem install ruby-debug19 and try it out:

 $ ruby -v -r rubygems -r ruby-debug -e 'Debugger.start and puts Debugger.current_context'
ruby 1.9.3p0 (2011-10-30 revision 33569) [x86_64-darwin11.2.0]
#<Debugger::Context:0x007fea0b8957e0>

Hooray! The future is now; you can get back to debugging your Rails 3.1 apps with ruby-debug on Ruby 1.9.3.

This probably isn’t the canonical solution—I’m no autotools or C expert—but it works for now. I’m sure they’ll fix it properly for the next release.

Monday, October 31st, 2011 reblogged from Mario's Blog

Declarative cucumber scenario's »

mariovisic:

I did a tech talk at work about how we were using cucumber and how we should be using it instead. It goes over using declarative cucumber scenarios instead of imperative.

Slides are here: mariovisic.github.com/Cucumber- Examples/

Tuesday, October 25th, 2011

Microwave Self-Saucing Chocolate Pudding in a Cup

After sampling various microwave desserts in a cup, I was craving my favourite—self-saucing chocolate pudding. The Internet failed to provide a microwave cup recipe so I adapted a larger one. On my third attempt I discovered the perfect recipe:

In a cup or ramequin combine

  • 1.5 tbsp sr flour
  • 1.5 tbsp sugar
  • 1.5 tbsp cocoa
  • 1.5 tbsp milk

and spoon mix until smooth.

Sprinkle

  • 1/2 tbsp cocoa
  • 1 tbsp brown sugar

on top, then carefully pour on

  • 1 tbsp hot water.

Put it on a saucer—it might overflow—and microwave for 30s. Time may vary based on the power of your microwave, try 1m on medium if this doesn’t work for you. You want it to look cakey on top but still be liquid underneath.

Enjoy!

Friday, September 16th, 2011

Using ruby-debug on Ruby 1.9.3 preview1

UPDATE: confirmed still problematic on ruby 1.9.3 rc1. This fix still works. (Thanks @janminarik!)

Ruby 1.9.3 preview1 has a slightly broken build process. In the final step of compilation it hides a number of symbols while linking the ruby binary. This means ruby-debug’s extension can’t get all the information it needs to make the debugger work and it breaks.

To fix, first grab some coffee, tenderlove-style.

You need to recompile after removing a line from configure.in. Make sure you’ve got a copy of the ruby 1.9.3 preview1 source then apply this patch:

$ git apply <( curl https://github.com/ruby/ruby/pull/47.diff )

Recompile:

$ autoconf && ./configure --prefix="$HOME/.rbenv/versions/1.9.3-preview1" && make -j3

Double check it’s worked by checking the _ruby_current_thread symbol is visible (or you can just trust me):

$ nm ruby | grep current_thread
00000001002249d0 D _ruby_current_thread

Then install as normal (make install), set up rubygems, gem install ruby-debug19 and try it out:

 $ ruby -v -r rubygems -r ruby-debug -e 'Debugger.start and puts Debugger.current_context'
ruby 1.9.3dev (2011-07-31 revision 32780) [x86_64-darwin11.0.1]
#<Debugger::Context:0x007ff1e2450fe8>

Hooray! The future is now; you can get back to debugging your Rails 3.1 apps with ruby-debug on Ruby 1.9.3.

This probably isn’t the canonical solution—I’m no autotools or C expert—but it works for now. I’m sure they’ll fix it properly for the next release.

Wednesday, April 20th, 2011

Parse a natural duration into seconds in JavaScript

I wrote this for a little Chrome extension I maintain and thought it might be useful to someone else. It parses a natural language duration like “1h30m” or “37 days, 1 hr, 3 mins and 7s” into a straight number of seconds.

Thursday, April 14th, 2011

How to install Pow from source on OS X

A couple of people have asked me, so:

  1. Install Xcode if you haven’t already.
  2. Install Homebrew and be one of the cool kids:
    curl https://gist.github.com/raw/323731/install_homebrew.rb | bash
  3. Install Node.js:
    brew install node
  4. Install npm:
    curl http://npmjs.org/install.sh | sh
  5. Clone pow git repository somewhere safe (I use ~/Development):
    git clone https://github.com/37signals/pow.git
  6. Inside your new pow checkout, install the development dependencies. Run:
    npm install --dev
  7. If you haven’t installed Pow before, setup the ~/.pow directory:
    mkdir -p ~/Library/Application\ Support/Pow/Hosts && ln -s ~/Library/Application\ Support/Pow/Hosts ~/.pow

    and the firewall forwarding and resolvers:

    sudo ./bin/pow --install-system
    sudo launchctl load /Library/LaunchDaemons/cx.pow.firewall.plist
  8. Finally, run pow (send an interrupt to quit):
    ./bin/pow

You’ve a couple of other options. Get a list of cake tasks with ./node_modules/coffee-script/bin/cake then run tasks with ./node_modules/coffee-script/bin/cake <task> (or install cake globally — it’s similar to make or rake but for coffee script). You can also check out the Cakefile. A good one is cake watch which will stay running and watch your coffee files for changes, recompiling them into javascript as neccessary.

If you don’t already have pow installed, you’ll need to create the firewall rule to forward all port 80 traffic to pow and add the DNS resolver for the dev TLD. To do this, run cake install as above.

Have fun!

Tuesday, April 12th, 2011

Pow via Bonjour

I fell in love with Pow the moment it was released. Easily deployed multi-app multi-ruby rvm-aware rack development? <3!

I’ve modified Pow so it publishes via mDNS, also known as Bonjour. This means you can send someone across the office a link to your current development copy of an app to break for you.

Anything that works at http://myapp.dev will also work at http://myapp.mycomputer.local within the local network. If you don’t know what your computer name is, look in the Mac OS X Sharing preference pane. It handily tells you the name that other computers can access your computer via.

There are a few caveats, and there’s still quite a bit to do… it doesn’t notice changed hostnames, doesn’t say goodbye when leaving (host entries may linger for other users), it doesn’t publish _http._tcp services for browsability (but who uses this anyway), and it only publishes the default route over all interfaces so if your network topology is the least bit interesting it might break.

The code’s on GitHub:

https://github.com/sj26/pow

I don’t want to publish a release contrary to 37signals’, so it’s from-source installation only. There’s a discussion about the feature and a pull request, so I hope it might get into master. I hear from-source instructions are coming. Until then, see this discussion.

Monday, April 11th, 2011

Nice nested layouts »

I really wanted a nicer way of doing nested layouts using HAML in Rails. The rails example including yield(:content) || yield makes me want to heave. Okay, so they use content_for? now, but it’s still horrid, and what happens when you’re more than one or two levels deep?

Ideally, layouts should be able to dictate they inherit from something else. Partially inspired by the NestedLayouts plugin for Rails 2, the best way to do this I could come up is to use a capture block in my layout. This means I can use:

Inside my application layout:

and now use layout :admin in my admin controllers:

and it will nest nicely as expected.

The helper itself looks like:

and these extracts are all part of this gist.

I hope you find it useful too. Have fun!