Posted 4 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home
Web apps often move long-running processes (such as delivering email) out of the request/response cycle into a queue of background jobs. A worker process then picks up those jobs from the queue and runs them in the background.
In acceptance tests, it’s desirable to run those background jobs immediately, skipping the queueing component, to avoid writing custom code to work the jobs off.
Configure RSpec request specs with a custom run_background_jobs_immediately method:
RSpec.configure do |config|
# if you're using Capybara 1.x, :feature should be replaced with :request
config.around(:each, type: :feature) do |example|
run_background_jobs_immediately do
example.run
end
end
config.include BackgroundJobs
end
A Delayed::Job implementation of the method:
# spec/support/background_jobs.rb
module BackgroundJobs
def run_background_jobs_immediately
delay_jobs = Delayed::Worker.delay_jobs
Delayed::Worker.delay_jobs = false
yield
Delayed::Worker.delay_jobs = delay_jobs
end
end
A Resque implementation of the method:
# spec/support/background_jobs.rb
module BackgroundJobs
def run_background_jobs_immediately
inline = Resque.inline
Resque.inline = true
yield
Resque.inline = inline
end
end
Voilà.
Posted 4 months back at The Pug Automatic
I read through :help rails.txt to see if Rails.vim included anything useful that I wasn’t using already.
The biggest discovery was how customizable it is.
Customize alternate file mappings
Rails.vim lets you jump between “alternate files” with :A. Typically, that’s something like app/models/item.rb ↔ spec/models/item_spec.rb.
If you stray too far from the Rails conventions, though, :A can no longer help you.
We have a Rails-less test suite in unit and engines right inside the main app for technical reasons. When we’re working on any of those files, :A does not work and we grumble. Clearly we were not intended to test things outside Rails.
But it turns out it’s fairly easy to add your own mappings, even with fallbacks. This is now in our Vim configs:
<figure class="code">
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| " :A on lib/foo.rb -> unit/lib/foo_spec.rb
autocmd User Rails/lib/* let b:rails_alternate = 'unit/' . rails#buffer().name()[0:-4] . '_spec.rb'
" :A on unit/lib/foo_spec.rb -> lib/foo.rb
autocmd User Rails/unit/lib/* let b:rails_alternate = rails#buffer().name()[5:-9] . '.rb'
" :A on engines/foo/bar.rb -> {spec,unit}/engines/foo/bar_spec.rb
autocmd User Rails/engines/* let common = rails#buffer().name()[0:-4].'_spec.rb' | let spec = 'spec/'.common | let unit = 'unit/'.common | let b:rails_alternate = filereadable(spec) ? spec : unit
" :A on spec/engines/foo/bar_spec.rb -> engines/foo/bar.rb
autocmd User Rails/spec/engines/* let b:rails_alternate = rails#buffer().name()[5:-9] . '.rb'
" :A on unit/engines/foo/bar_spec.rb -> engines/foo/bar.rb
autocmd User Rails/unit/engines/* let b:rails_alternate = rails#buffer().name()[5:-9] . '.rb'
|
</figure>
Note that in the third example, it looks for an alternate in spec, with unit as a fallback.
Though I haven’t seen a use for it yet, you could change the :R “related file” mappings in much the same way. Maybe to jump between your two god classes?
Customize navigation commands
Rails.vim comes with commands like :Rmodel and :Rcontroller to open a certain type of file with autocompletion.
Turns out you can add your own navigation commands. I added two, for Fabrication (which we’re moving away from) and FactoryGirl factories:
<figure class="code">
1
2
3
4
5
| " :Rfac item
autocmd User Rails Rnavcommand factory spec/factories -suffix=_factory.rb
" :Rfab item
autocmd User Rails Rnavcommand fabricator spec/fabricators -suffix=_fabricator.rb
|
</figure>
With that, you simply run :Rfac item<Enter> or :Rfac it<Tab><Enter> to open spec/factories/item_factory.rb.
Posted 4 months back at Ruby5
Rails security is getting better all the time, CanBe better than STI, super fast Ruby execution with RubyFlux, no more yaml, dismissable info messages, and better presenters with resubject all in this episode of Ruby5.
Listen to this episode on Ruby5
Rails Security Updates
Update your apps again there are new Rails security patches.
This episode is sponsored by New Relic
New Relic is _the_ all-in-one web performance analytics product. It lets you manage and monitor web application performance, from the browser down to the line of code. With Real User Monitoring, New Relic users can see browser response times by geographical location of the user, or by browser type.
CanBe
STI got you down? Forget the antibiotics and check out CanBe!
RubyFlux
Statically compile your Ruby code to Java for some crazy performance improvements.
Turtles All The Way Down
Embrace Ruby’s Lisp heritage and ditch YAML as a configuration default.
dismissable_helpers
Add 'Never show me again' messaging to your app with ease.
Resubject
There's a new presenter gem on the scene that is really clean and simple to use.
Posted 4 months back at blah blah woof woof articles
Every time I use AngularJS I love it a little more. One of my favourite things about it is how greatly it reduces ceremony and separation. When I’m writing front-end interactions, the last thing I want to be doing is jumping between files and maintaining state in two different places, especially for simple things like “click to edit” behaviour. That’s what I’ll show you now, done powerfully and directly in Angular:
<div ng-app>
<div ng-controller="ClickToEditCtrl">
<div ng-hide="editorEnabled">
{{title}}
<a href="#" ng-click="editorEnabled=!editorEnabled">Edit title</a>
</div>
<div ng-show="editorEnabled">
<input ng-model="title">
<a href="#" ng-click="editorEnabled=!editorEnabled">Done editing?</a>
</div>
</div>
</div>
Try this jsfiddle to see it in action. What we’re doing is showing some text (an article’s title in this example) and then revealing a field to edit it upon clicking an “Edit” link.
To achieve this, we use an Angular editorEnabled model (really just a flag here) that we check with ng-show and ng-hide directives to hide and show the various parts of the interface. We change this value using an ng-click directive on the hide and show links. Angular’s data binding keeps everything in sync. As soon as editorEnabled flips between true and false, the interface reacts accordingly. And the best thing? Everything you need can be written directly in the markup.
The only bit of JavaScript is just the most basic setup for the Angular controller, providing an initial value for the title:
function ClickToEditCtrl($scope) {
$scope.title = "Welcome to this demo!";
}
For some more sophisticated behaviour, you can put some more code in the controller. Let’s change the interface to show “save” and “cancel” links when editing the title, and only update the title if the “save” link is pressed:
<div ng-app>
<div ng-controller="ClickToEditCtrl">
<div ng-hide="editorEnabled">
{{title}}
<a href="#" ng-click="enableEditor()">Edit title</a>
</div>
<div ng-show="editorEnabled">
<input ng-model="editableTitle" ng-show="editorEnabled">
<a href="#" ng-click="save()">Save</a>
or
<a href="#" ng-click="disableEditor()">cancel</a>.
</div>
</div>
</div>
See it in this jsfiddle.
The code in the corresponding controller doesn’t need to worry about the interface at all, it just operates on the scope, and the interface updates itself accordingly.
function ClickToEditCtrl($scope) {
$scope.title = "Welcome to this demo!";
$scope.editorEnabled = false;
$scope.enableEditor = function() {
$scope.editorEnabled = true;
$scope.editableTitle = $scope.title;
};
$scope.disableEditor = function() {
$scope.editorEnabled = false;
};
$scope.save = function() {
$scope.title = $scope.editableTitle;
$scope.disableEditor();
};
}
If you wanted to extend this even further and make it a reusable component for different parts of your interface, you would make it a custom directive.
One of the other great things about AngularJS is that you can use it as much or as little as you like. We’ve used it for the entirety of The Thousands’ admin interface, so adding bits of behaviour like this is no problem. But even if you’re not already using it, you can just as easily attach an ng-app to any one of your HTML elements and get started.
Posted 4 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home
Zeus improves Rails boot time. Saving seconds is most important when running focused tests:
rspec spec/models/user_spec.rb
rspec spec/models/user_spec.rb:123
Those are times when a tight feedback loop make a meaningful difference.
Install
Install the Zeus gem on your machine:
gem install zeus
Do not include it in your Gemfile. It is an external piece of software.
Set up
Initialize:
zeus init
This will create two files in your Rails app’s directory. Ignore them globally in ~/.gitignore:
custom_plan.rb
zeus.json
Edit zeus.json to include only the tasks for which you’ll use Zeus. Mine looks like this:
{
"command": "ruby -rubygems -rzeus/rails -eZeus.go",
"plan": {
"boot": {
"default_bundle": {
"development_environment": {
"prerake": {"rake": []},
"console": ["c"],
"generate": ["g"],
},
"test_environment": {
"test_helper": {"test": ["rspec"]}
}
}
}
}
}
I remove cucumber in favor of RSpec and Capybara. I remove server in favor of Foreman and Pow.
Force the test environment
In spec/spec_helper.rb, change:
ENV['RAILS_ENV'] ||= 'test'
To:
ENV['RAILS_ENV'] = 'test'
Remove auto-running code
The goal is to run tests in the context of Zeus. So, remove other similar systems.
From the RSpec docs:
Generally, life is simpler if you just use the rspec command. If you
must use the ruby command, however, you’ll want to do the following:
require 'rspec/autorun'
This tells RSpec to run your examples.
We don’t need this behavior and can cause bugs when used with Zeus.
Remove either of these lines in spec/spec_helper.rb if they exist:
require 'rspec/autorun'
require 'rspec/autotest'
Remove Spork and Guard
For the same reasons, if you’re using Spork and Guard, delete them from your Gemfile, delete your Guardfile, and delete any related Spork code in spec/spec_helper.rb or spec/support/.
Start Zeus
Zeus will need to be running before you can use its commands:
zeus start
I usually run this, and other long-running processes in a tmux session.
Now, those original commands will have the benefit of Rails boot time in under a second:
zeus rspec spec/models/user_spec.rb
zeus rspec spec/models/user_spec.rb:123
Bonus: run specs from vim
Many of us are running specs directly from vim. If you edit your ~/.vimrc to use Zeus like in this commit, you can run focused specs with:
<Leader>t
Enjoy!
Posted 4 months back at Phusion Corporate Blog
Phusion Passenger is an Apache and Nginx module for deploying Ruby and Python web applications. It has a strong focus on ease of use, stability and performance. Phusion Passenger is built on top of tried-and-true, battle-hardened Unix technologies, yet at the same time introduces innovations not found in most traditional Unix servers. Since mid-2012, it aims to be the ultimate polyglot application server.
Recent changes
Phusion Passenger is under constant maintenance and development. New features will be introduced in Phusion Passenger 4. In the mean time, the Phusion Passenger 3 branch receives bug fixes only.
Phusion Passenger also has an Enterprise version which comes with a wide array of additional features. With the released of the open source Phusion Passenger 3.0.19, Phusion Passenger Enterprise has also been updated at the same time. By buying Phusion Passenger Enterprise you will directly sponsor the development of the open source version.
- Nginx security fix: do not display Nginx version when server_tokens are off.
- Fixed compilation problems on some systems, such as Fedora 17.
- Fixed Union Station compatibility with Rails 3.2 and other Union Station-related bugs.
- Phusion Passenger Enterprise Standalone now supports rolling restarts and deployment error resistance.
How do I upgrade to 3.0.19?
Please refer to the upgrade instructions in the manual:
Final
The open source Phusion Passenger is provided to the community for free. We also provide an Enterprise version which comes with a wide array of additional features. Development of the open source version is directly sponsored by Enterprise sales. If you like Phusion Passenger, or if you would like to use the Enterprise features, please consider buying one or more licenses. Thank you!
Phusion Passenger is regularly updated and we regularly release new and interesting products! We have many exciting things planned for the near future. Curious? Enter your email address and name below and we’ll keep you up to date.
The post Phusion Passenger 3.0.19 released appeared first on Phusion Corporate Blog.
Posted 4 months back at blah blah woof woof articles

It's been a while since we've talked about Decaf Sucks on the iPhone. Our first release has run smoothly for a year and a half, helping many thousands of iPhone owners find better coffee. Thanks to our well caffeinated contributors, nearly half of our reviews are now submitted from the app.
On this note, we're very excited to announce the release of Decaf Sucks version 1.1 in the App Store. This release makes it even easier to contribute reviews with the addition of Facebook login support (now available wherever Decaf Sucks exists).
We've also added support for the iOS 6 and the larger iPhone 5 display, as well as giving the app some extra polish all around. In particular, our overseas friends can rest easy, because the distance to your favourite cafes is now reported in miles or kilometres based on the device's region format setting.
Decaf Sucks 1.1 is still free and waiting for you in the App Store. Get it now and find some great coffee near you!
Read on for a full list of all the things we've changed.
New features:
- Login with Facebook to write reviews
- Support for the larger iPhone 5 display
- Distance units are localised into miles or kilometres based on the device's settings
- iOS 6 compatibility updates
Other improvements:
- When setting a cafe's location, show a callout above the map pin to make it clear that it can be dragged around.
- When setting a cafe's location, ensure that the pin is actually draggable on the first tap.
- When setting a cafe's location, always show a proper full address after dragging the pin around.
- Show a proper non-retina image for the back button's pressed state.
- Fix a bug that sometimes caused the map view to start very zoomed out.
- When a review is completely empty, make sure the "Post" button stays disabled.
- Ensure the map for a single cafe encompasses the current location, if it is nearby.
- Fix a bug that led to some reviews being set to Hyderabad, India. Yes, this was really weird.
Decaf Sucks 1.1 is available in the App Store now.
Posted 4 months back at blah blah woof woof articles
It’s been a while since we’ve talked about Decaf Sucks on the iPhone. Our first release has run smoothly for a year and a half, helping many thousands of iPhone owners find better coffee. Thanks to our well caffeinated contributors, nearly half of our reviews are now submitted from the app.

On this note, we’re very excited to announce the release of Decaf Sucks version 1.1 in the App Store. This release makes it even easier to contribute reviews with the addition of Facebook login support (now available wherever Decaf Sucks exists).
We’ve also added support for the iOS 6 and the larger iPhone 5 display, as well as giving the app some extra polish all around. In particular, our overseas friends can rest easy, because the distance to your favourite cafes is now reported in miles or kilometres based on the device’s region format setting.
Decaf Sucks 1.1 is still free and waiting for you in the App Store. Get it now and find some great coffee near you!
Read on for a full list of all the things we’ve changed.
New features:
- Login with Facebook to write reviews
- Support for the larger iPhone 5 display
- Distance units are localised into miles or kilometres based on the device’s settings
- iOS 6 compatibility updates
Other improvements:
- When setting a cafe’s location, show a callout above the map pin to make it clear that it can be dragged around.
- When setting a cafe’s location, ensure that the pin is actually draggable on the first tap.
- When setting a cafe’s location, always show a proper full address after dragging the pin around.
- Show a proper non-retina image for the back button’s pressed state.
- Fix a bug that sometimes caused the map view to start very zoomed out.
- When a review is completely empty, make sure the “Post” button stays disabled.
- Ensure the map for a single cafe encompasses the current location, if it is nearby.
- Fix a bug that led to some reviews being set to Hyderabad, India. Yes, this was really weird.
Decaf Sucks 1.1 is available in the App Store now.
Posted 4 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home
Web app development/production parity can be improved by defining process types in a manifest named Procfile such as this one for a Rails app:
web: bundle exec rails server thin -p $PORT -e $RACK_ENV
In production, Heroku’s Cedar stack reads process types from that file.
In development, Foreman manages output streams, responds to crashed processes, and handles user-initiated restarts and shutdowns.
One downside to Foreman is typing http://localhost:3000, http://localhost:3100, etc. into the web browser, incrementing the port number for each app, forgetting which port is which app.
Pow solves this elegantly and is easy to install and maintain.
Pow has a DNS server, capable of port proxying to Rack apps.
Install and run Pow:
curl get.pow.cx | sh
Configure Foreman to always use the same port:
cd /path/to/myapp
echo “port: 7000” > .foreman
Relate the port to Pow:
echo 7000 > ~/.pow/`basename $PWD`
Use Foreman normally:
foreman start
Reap the benefits of well-named DNS like http://myapp.dev.
It’s possible Pow may see improved, or automatic, Foreman compatibility. Watch this pull request for updates.
Posted 4 months back at The Pug Automatic
If you’re migrating a lot of data, you may feel the need for SQL updates with joins.
Active Record doesn’t have an abstraction for this, but you can run the SQL manually.
Note that this is for Postgres. The syntax likely differs for other database engines.
It took me a while to figure out the syntax the first time I did it, though, so here it is for reference.
In this contrived example, an order belongs to an item which belongs to a company, and you want to set every order’s company_code from its item’s company’s code.
<figure class="code">
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| class MyMigration < ActiveRecord::Migration
def up
update_sql("
UPDATE orders
SET company_code = companies.code
FROM items, companies
WHERE
orders.item_id = items.id AND
items.company_id = companies.id
")
end
def down
# Whatever.
end
end
|
</figure>
Posted 4 months back at Ruby5
Back into the swing of things we discuss Ruby 2.0.0-rc1, dismissible helpers, the engine yard awards, speeding up travis build time, binstubs, hacker term, rails panel, and the sd ruby podcast.
Listen to this episode on Ruby5
This episode is sponsored by Top Ruby Jobs
If you're looking for a top Ruby job or for top Ruby talent, then you should check out Top Ruby Jobs. Top Ruby Jobs is a website dedicated to the best jobs available in the Ruby community.
Ruby 2.0.0-rc1 released
Ruby 2.0.0 RC1 is out, and RC2 and the full release aren’t far behind.
Dismissible Helpers
Dockyard brings us a gem that lets you offer website popup tips or instructions that can be dismissed by your users and remember using a cookie that they've been dismissed.
Engine Yard Awards
Engine Yard has recognized Luis Laverna, Nathan Harvey, Hiro Asari, and Elizabeth Marie Smith for innovation in our industry.
Speed up Travis CI Build Time
Travis build times getting you down? Michał Czyż shows you how to cut out huge chunks of time.
Understanding Binstubs
Mislav Marohnić gives a handy primer on how rubygems and rbenv handle executable commands that come packaged with gems.
hacker term
Ciaran Archer’s created a beautiful command line hacker news reader. Also serves as a good code sample of how to create command line applications in Ruby.
rails panel
Rails Panel is a Chrome extension that allows you to check your development log from inside Chrome’s Dev Tools.
SD Ruby Podcast
Need input on scaling your Rails app? Richard Schneeman gives you everything you need to know in this video from the San Diego Ruby Group.
Posted 4 months back at Jay Fields Thoughts
If you read my blog you've probably heard "code is data, data is code" and at one time and you've looked up homoiconicity. You may have deeply understood the idea the first time you heard it; I definitely did not. However, a recent addition to expectations opened my eyes to how truly powerful this programming language property can be.
I'll start by admitting what I heard when I originally encountered homoiconicity. Stuart Halloway had begun promoting Clojure, and homoiconicity was one of the advantages he noted. I hit the wikipedia page, digested the words "code is data, data is code", and thought to myself: well, yeah, obviously. I'd spent plenty of time working with DSLs in Ruby, and I had plenty of experience evaluating code in various contexts. I thought something along the lines of: So you capture the code as data and evaluate it wherever it makes sense, I don't see the big deal. In short, I didn't get it.
Fast forward a few years and several hours of full time Clojure development and you'll find me adding interaction based testing to expectations. What I had in mind for testing interactions was simple, I want to write exactly the same thing for the test as what I write for the production code. Additionally, I want the format of the test to follow the same format that is used for state based testing: (expect expected actual)
Once I had a clear vision for my requirements, the format of the tests became easy to visualize. Assume I have a function that prints to standard out, and I want to test that this print occurs.
<script src="https://gist.github.com/4487632.js"></script>
The above test looks great, but (println 5) will be evaluated, return nil, and use nil as the expected value. I needed some way for the programmer to tell the testing framework that this was an interaction test, and expectations needed to verify that the function was called with the specified parameters. After trying a few different formats, I settled on the following solution.
<script src="https://gist.github.com/4487690.js"></script>
By wrapping the interaction I wanted to test with (interaction ...), I created an easy way to identify and capture the function and arguments that needed to be verified.
Once I'd decided on the syntax, I went about the task of adding support to expectations. If you dug into the implementation of expectations, you'd find that expect is a macro that delegates the handling of the "expected" and "actual" arguments to the doexpect macro. The first thing the doexpect macro does is check if expected is a list and (if so) if the first argument is the symbol "interaction" (source here). If the first argument is not a list that begins with 'interaction, then the data is passed to do-value-expect and expanded more or less as is. However, if the first argument is a list that begins with 'interaction, then the data is passed to do-interaction-expect, and do-interaction-expect then destructures the data, grabbing only the pieces of the list that it cares about (source here). When I wrote this code, I found it very interesting.
When I envisioned the interaction syntax, I assumed that (interaction ...) would be a call to a macro, and I would need to need to manipulate the data passed to interaction. However, once I got into the actual implementation, I found myself using the symbol "interaction", but never actually defining a macro or even a function. That's when homoiconicity really started to become clear to me. I'd written code that I was sure would need an implementation, yet it was used exclusively as data.
If you kept digging into this example you would find that anything found within (interaction ...) is never used as written, but is instead expanded in a way that allows expectations to rebind the specified function and use the expected arguments at verification time. As a result, you write the same code in the same way but within your test it's used exclusively as data and in your production code it's used exclusively as code. I'm a big fan of convention, and there's no better convention than 'use the exact same thing'.
I later added the ability to add interaction tests for calls to Java objects as well, which led to the following behavior for expectations.
- If your expected value is not an interaction, it will be expanded as is.
- If your expected value is an interaction with a Clojure function, it will be used as data exclusively and expanded to rebind the function, capture all calls to the function and verify that a call occurred with the arguments you specified.
- If your expected value is an interaction with a Java method, it wil be used as data exclusively and expanded to mockito setup and verification code.
Thus, an expected value is sometimes code, and sometimes data.
Posted 4 months back at ChadFowler.com
It’s hard to believe it’s been almost two years since InfoEther was acquired by LivingSocial. Since then, we’ve built the strongest development team I’ve ever known. We’ve set records for e-commerce transaction volume. We’ve grown at an incredible pace, both as a business and as technology team. We’ve shipped a lot of software, and made millions of people’s lives more interesting in the process. I’ve had the privilege to work with some of the most admired engineers in on industry. I’m proud of the team Aaron Batalion (from whom I’ve learned a ton about running a consumer internet product) had assembled before InfoEther arrived and of the team that ultimately grew from that foundation.
As I mentioned when I announced our Hungry Academy program, for me personally the experience at LivingSocial has been intense. As I said in that post, “These last 8 months at LivingSocial have been the best 4 years of my career.” That holds true today.
Playing the role of Senior Vice President of Technology and serving on the senior executive team at LivingSocial has been a rewarding learning experience. I’m humbled by the talent and experience of every member of that team, and since my first day have been awed by Tim O’Shaughnessy’s business sense and natural leadership ability. I look back on my career, and a handful of teachers and mentors stand out that have had a significant impact on me. Tim is now in that very short list.
All the while, though, I’ve known that I would eventually go back to a more hands-on role, personally building products and solving technical problems. I am, after all, a Passionate Programmer.
Kelly and I have also had a goal to (before we get too old to fully enjoy it) live overseas again. Our time in India, was a huge influence on both of us, both personally and professionally, and we’ve long since hoped to gain a similar experience in a different part of the world, specifically Europe.
So that’s what we’re going to do. I’m taking a role as CTO of a technology startup in one of our favorite cities: Berlin. I’ll be working hands-on to develop cross-platform software with a small, talented team of engineers, designers, and product managers. I’ll be transitioning from my role at LivingSocial for the remainder of January and will be relocated to Berlin and starting the new job in mid February.
As excited as I am to move to the next adventure, it’s always sad leaving a great company like LivingSocial. I’ve made some friendships that will last forever, and I’ll miss the team immensely. I know, however, that they’re in good hands and that 2013 is going to be a fantastic year for the business.
Posted 4 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home
Since launching Ruby Science we’ve written and released five new chapters. If you’ve previously purchased the book, you can log into GitHub to download the latest version.
Here’s what we’ve added:
Code smells
Solutions
- Introduce Explaining Variable
- Introduce Form Object
- Move Method
The book is a work in progress, and we’ve now got around 60 pages of content. The purchase also includes support for any Ruby, Rails, and Refactoring questions. You can get access now for an early purchase price of $39. This will increase to $49 on January 31, 2013.
Download a free sample of Ruby Science today.
Posted 4 months back at Mike Mondragon
I gave a lightening talk about IRB (Interactive Ruby Shell) at Seattle.rb on 01/08/2013.
Here is my speaker deck:
https://speakerdeck.com/monde/seattle-dot-rb-irb-presentation
Here my notes and example irbrc's:
http://bit.ly/seattle-rb-irb
The irbtools gem is really massive in all of the features it curates together. As mentioned in the deck, I prefer a more simple setup of:
- integrated vim to edit/paste code via the interactive editor gem
- load/save command history (require 'irb/ext/save-history')
- tab completion on object methods (require 'irb/completion')