A few hints when upgrading to Ruby 1.9

Note: If you are currently working with Ruby 1.8.7 or 1.9.3, we recommend to upgrade to Ruby 2.1 first. From our experience this upgrade is much smoother than the jump from 2.1 and 2.2, while still giving your the huge performance gains of Ruby 2. Also, if you're on Ruby 1.8.7, we recommend to skip a troublesome upgrade to 1.9.3 and go straight to 2.1.


When trying to make a Rails app run on Ruby 1.9, you're likely to encounter several issues. Here are a few solutions (obviously not exhaustive):

When running `bundle ...

Change file permissions with Ruby

You can say

File.chmod(0604, '/path/to/file') # rw----r--

The leading zero is meaningful.

Fix for: Your Firefox profile cannot be loaded. It may be missing or inaccessible.

If you use Selenium and Launchy to open web pages, you might run into an error saying "Your Firefox profile cannot be loaded. It may be missing or inaccessible.".

This happens because Launchy tries to use your Firefox running the web driver to open the page.

For Launchy < 0.4.x, as a workaround you can set an environment variable

export LAUNCHY_BROWSER=`which google-chrome`

For newer Launchys you also need to set:

export BROWSER=`which google-chrome`

If you want to do this in a ruby script, you can say

chrome_path ...

Shell script to generate a Git commit with Pivotal Tracker story ID and title

We usually generate our commit messages from Pivotal Tracker IDs and titles, like
[#15775609] Index view for conflicts

The geordi command commit automates this. (See: Pretty Commit messages via geordi).

Just run geordi commit and it will connect to PT and let you select from a list of all started and finishes stories. Then it runs git commit with the generated message (i.e. all staged changes will be commited).

When running for the first time, Geordi will request your PT...

Fix "private method `select' called for Capybara::Node::Element

API breakage ahoy. You need to either upgrade your Capybara or downgrade your selenium-webdriver gem.

Alternatively, this could solve your trouble.

Linux: Create file of a given size

Sometimes you need a file of some size (possibly for testing purposes). On Linux, you can use dd to create one.

Let's say you want a 23 MB file called test.file. You would then run this:

dd if=/dev/zero of=test.file bs=1048576 count=23

The block size (bs) is set to 1 MB (1024^2 bytes) here, writing 23 such chunks makes the file 23 MB big.\
Adjust to your needs.

This linux command might also come in handy in a Ruby program. It could be used like:

mb = 23
mb_string, _error_str, _status = Open3.capture3('dd if=/dev/zero...

Hoptoad is now Airbrake

We are changing our name from Hoptoad to Airbrake. You see, some folks much larger than us reached out and claimed trademark over all things related to frogs and toads and little animals of that ilk. After speaking to our lawyers we reluctanctly decided it’s best to change the name.

Check gem dependencies before installation

With gem dependency it is possible to check the dependencies for your gem before you install it.

Here is an example output for Nokogiri:

Gem nokogiri-1.4.4
  hoe (>= 2.6.2, development)
  minitest (>= 1.6.0, development)
  racc (>= 0, development)
  rake-compiler (>= 0, development)
  rexical (>= 0, development)
  rubyforge (>= 2.0.4, development)

Use look-behind assertions in regular expressions with Ruby 1.8

Regular expressions can have something called "zero-width look-behind assertions". This means that you want a pattern to be preceded by another pattern, but not include the preceding pattern in your match or search cursor. E.g. (?<=x)y matches y in xyz but not in syz. There are also negative look-behind assertions, e.g. (?<!x)y matches y in syz but not in xyz.

Unfortunately look-behind assertions are only available in Ruby 1.9. With Ruby 1.8 you need to use an alternative regular expression library called [Oniguruma](http://...

Installing Rails on a fresh system

  1. Install Ruby from the Ubuntu repository: sudo apt-get install ruby ruby-dev \
    ruby is the meta package. If you want to explicitly install 1.8 or 1.9, install ruby1.8 or ruby1.9 instead (the same applies for ruby-dev).
  2. Do not install RubyGems from the repository but install the version from the webpage instead.
  3. Get Bundler: sudo gem install bundler

Rails and other gems for a project should now be installed via bundle install from the...

console-for opens a Rails console remotely on a Capistrano deployment target

We're adding a script console-for to open a remote Rails console with one command. Also have a look at shell-for, which this script is relying on.

Run it from any project directory like this, passing a Capistrano multistage deployment target:

console-for staging

This script is part of our geordi gem on github.

Install the SQLite 3 gem for Ruby under Ubuntu

sudo apt-get install sqlite3 libsqlite3-dev
sudo gem install sqlite3-ruby

Hack of the day: A reverse for Rails' &:

Ever wondered if there is a reverse for Rails' .each(&:to_s) idiom? Turns out there is...

You probably already know, that you can abbreviate code like

dogs.each { |dog| dog.bark! }

with

dogs.each(&:bark!)

Now suppose it is the other way round and you have

bones.each { |bone| dog.eat!(bone) }

Good old Ruby already has a solution:

bones.each(&dog.method(:eat!))

Change the timestamp of a file in Ruby

This is somewhat similar to the touch command of Linux:

FileUtils.touch 'example.txt', :mtime => Time.now - 2.hours

If you omit the :mtime the modification timestamp will be set to the current time:

FileUtils.touch 'example.txt'

You may also pass an array of filenames:

FileUtils.touch %w[ foo bar baz ], :mtime => Time.now - 2.hours

Non-existent files will be created.

"no such file to load require_relative (MissingSourceFile)" after installing ruby-debug

If you encounter above mentioned failiure message after installing the ruby-debug gem then you have to explicitly require linecache version 0.43 in your Gemfile.

gem 'ruby-debug'
gem 'linecache', '=0.43'

Why developers should be force-fed state machines

Most web applications contain several examples of state machines, including accounts and subscriptions, invoices, orders, blog posts, and many more. The problem is that you might not necessarily think of them as state machines while designing your application. Therefore, it is good to have some indicators to recognize them early on. The easiest way is to look at your data model.

What’s Up With All These Changes in Rails?

Yesterday, there was a blog post entitled “What the Hell is Happening to Rails” that stayed at the number one spot on Hacker News for quite a while. The post and many (but not most) the comments on the post reflect deep-seated concern about the recent direction of Rails. Others have addressed the core question about change in the framework, but I’d like to address questions about specific changes that came up in the post and comments.

New Cucumber Factory makes it easier to associate records

I pushed a new version of the Cucumber Factory gem. This new release lets you refer to a previously created record by any string attribute:

Given there is a movie with the title "Before Sunrise"
And there is a movie with the title "Limitless"
And there is a movie with the prequel "Before Sunrise"

Note how we didn't have to explicitly give the prequel a name in the example above. This is still possible, but will rarely be necessary now:

Given "Before Sunrise" is a movie with...

A nicer way to run RSpec and/or Cucumber

geordi, our collection of awesome shell scripts, has been extended by three scripts to help you call RSpec or Cucumber:

cuc

This script runs Cucumber the way you want it:

  • Prints some line feeds to easily find your test results when you come back to the console later
  • Configures Cucumber to use cucumber_spinner if it is available in your Gemfile
  • Runs Cucumber under bundle exec
  • Uses an old version of Firefox for Selenium (Javascript) features...

How to test resource_controller hooks

When using the resource_controller gem you often hook onto events like this:
update.before do
do_something
end

For testing such things in your controller you should -- as always -- not trigger something that eventually calls the thing you want.\
Instead, in your specs, have resource_controller run those hooks like it does itself. Like that:

describe 'before update' do
 ...

Open a new tab with the current directory on a mac

I found a nice script on crazylittlehacks and modified it slightly. Put the attachment to /usr/local/bin, chmod +x and run it like this:

tab

You may also pass a command that will be run in that newly opened tab:

tab ruby script/server

Note: This does not play too nice with Visor, because Visor will always be "window 1" for AppleScript. By modifying the script and replacing in window 1 with `in window...

Dump a two-dimensional array to an Excel .xls spreadsheet

Copy the attached Ruby code to config/initializers, or paste it into your IRB console. You can now dump any two-dimensional array to an Excel .xls spreadsheet with a single method call:

table = [['user', 'email', 'hours']]
User.all.each do |user|
  table << [user.name, user.email, user.hours]
end

table.dump_to_excel('users.xls')

The first row in the array will be dumped as the table head in bold type.

You need the spreadsheet gem in your Gemfile.

Note that there is a [limit of 65535 rows](https://makandracard...

Gem Versioning and Bundler: Doing it Right

When running an executable, ALWAYS use bundle exec. In some cases, running executables without bundle exec may work, if the executable happens to be installed in your system and does not pull in any gems that conflict with your bundle. However, this is unreliable and is the source of considerable pain. Even if it looks like it works, it may not work in the future or on another machine. 

Execution of shell code in Ruby scripts

Deprecated ways to execute shell code in Ruby

This is just a reference for legacy code. For new code, always use capture3.

%x{ } or backticks – quick and easy

Returns the standard output of running the given command in a subshell. This is an alias for `...`, and you can use string interpolation.

Example:

name = 'ls'
result = `which #{name}`

It does not escape anything you inject in the string, so be aware of possible security vulnerabilities...