Ruby

Ruby is a dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.


Articles on Ruby

Ruby / RoR... Why not?

In response to common question: "I'd be curious as to why your friends want to move away from the RoR/Ruby space..."

Published on in Ruby

Bundle Faster, Save Time

Bundler just annouced 1.4.0.pre.1 with --jobs support, which allows for multithreading gem installs -- I haven't looked at the code, but my guess is it's making use of the JOBS flag support in gmake (which multithreads C compilation) for navtive libs.

Anyway, here's my quick timing comparison on bundling a very large project with hundrends of gems:

rm -rf vendor/bundle
bundle install --path vendor/bundle
# time: 5:31.40 total

rm -rf vendor/bundle
gem install bundler -v 1.4.0.pre.1 --pre
bundle install --jobs=4 --path vendor/bundle
# time: 3:10.38 total

Enjoy!

Published on in Ruby

Simple Rules for Stable, Performant and Maintainable Apps

Here are some simple and basic rules I've found for building applications that are maintainable and perform well, both in speed and stability. These rules, at one level or another, can apply to smaller modules and libraries, scripts, as well as fully featured large scale applications (both web and otherwise). In this post I will focus more on web applications, since that's where I've spent most of my time. At a higher level, they should apply to almost all areas of software development.

Autobench Release - 0.0.1alpha7

Commit Logs for Autobench Release's

Stubbing Binaries for Testing

Being a Dev Ops guy, I write gems, scripts and hacks that tend to hook in to system binaries. I know, it would probably be better to write C bindings, but heretofore that hasn't been something I really want to tackle. Additionally, I almost always write tests for my stuff. I've come across the problem where my tests pass locally, but not on Travis-CI.

Hello World: Sinatra vs. Node.js

Sinatra

require 'sinatra'
get '/' do
  "Hello World"
end

Express

var app = require('express');
app.get('/', function(req, res) {
    res.send("Hello World!");
});
app.listen(8000);

Hack: Deploying with git and rake-remote_task

This is an update to my previous post: Hack: Deploying with git, replacing the use of pure rake, for rake-remote_task.

Add the following to your Rakefile

require 'rake/remote_task'

set :domain,      ENV.fetch(PRODUCTION_HOST, "www.yourhost.com")
set :environment, ENV.fetch(RACK_ENV,        "production")

set :app_path,    "/path/to/app/install"

remote_task :deploy do
  run "set -x; cd #{app_path} && git pull && bundle"
end

remote_task :restart do
  run "set -x; cd #{app_path} && RACK_ENV=#{environment} bundle exec rake unicorn:restart --trace"
end

Then run

$ RACK_ENV=production PRODUCTION_HOST=www.foohost.com bundle exec rake deploy restart

or just

$ RACK_ENV=production PRODUCTION_HOST=www.foohost.com bundle exec rake deploy

Note -- This assumes the following:

  • You've checked out your repo on your remote host.
  • You've setup your app and it's running on your remote server.
  • You're using using Unicorn.
  • You're using Bundler.

Installing Nginx with Lua Module

Download the script.

Or run the following command:

bash < <(curl -s https://gist.github.com/jmervine/5407622/raw/nginx_w_lua.bash)

Note: This script has been tested on Ubuntu 12.04.2 LTS but should work on just about any unix based distro, as everything is compiled from source.

Requires wget and basic build essentials.

What's it do?

  • Download LuaJIT 2.0.1
  • Install LuaJIT 2.0.1
  • Download Nginx Development Kit (NDK)
  • Download lua-nginx-module
  • Download Nginx 1.2.8
  • configure Nginx with lua-nginx-module
  • Install Nginx

Binary Results:

  • /opt/nginx/sbin/nginx
  • /usr/local/bin/lua
  • /usr/local/bin/luajit

Lib Results:

  • /usr/local/lib/*lua*

Include Results:

  • /usr/local/include/luajit-2.0/*

Starting Nginx

LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH /opt/nginx/sbin/nginx -c /path/to/nginx.conf

Update existing Nginx init:

Stop Nginx: sudo /etc/init.d/nginx stop

Patch /etc/init.d/nginx like so:

13,14c13,18
< PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
< DAEMON=/usr/sbin/nginx
---
> export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
> 
> # ensure default configuration location
> test "$DAEMON_OPTS" || DAEMON_OPTS="-c /etc/nginx/nginx.conf"
> PATH=/opt/nginx/sbin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
> DAEMON=/opt/nginx/sbin/nginx`

Note: the above may not be the best way, but it's what I had to do to get it to work and I didn't have a ton of time to mess with it.

HTTPerf.rb Example

Here's an example of a simple script using HTTPerb.rb. It's a quick and dirty script used for getting quick differences between changes.

HTTPerf.rb 0.3.11 Released

Adding tee support, which will print any httperf (both STDOUT and STDERR) output to STDOUT while running the process.

LA Ruby Conf

LA Ruby Conf

I'll be there, say "Hello"!

Published on in Ruby

'starts_with?', 'end_with?' and 'include?' vs. RegExp

A co-worker of mine pointed out today that using Ruby's native methods for string matching is actually faster then using regular expressions. This was hard for me to believe to so I benchmarked them.

Setup the Benchmark

[1] pry(main)> require 'benchmark'
=> true
[2] pry(main)> test_string = "/foo/bar/bah/bing"
=> "/foo/bar/bah/bing"

String#starts_with?

[3] pry(main)> Benchmark.realtime { (1..10000).to_a.each { %r{^/foo}.match(test_string) } }
=> 0.009987447
[4] pry(main)> Benchmark.realtime { (1..10000).to_a.each { test_string.start_with?("foo") } }
=> 0.003103276

String#end_with?

[5] pry(main)> Benchmark.realtime { (1..10000).to_a.each { %r{bing$}.match(test_string) } }
=> 0.015837275
[6] pry(main)> Benchmark.realtime { (1..10000).to_a.each { test_string.end_with?("bing") } }
=> 0.005633547

String#include?

[7] pry(main)> Benchmark.realtime { (1..10000).to_a.each { %r{^.*bar.*$}.match(test_string) } }
=> 0.025630178
[8] pry(main)> Benchmark.realtime { (1..10000).to_a.each { test_string.include?("bar") } }
=> 0.010360719

Quick Benchmarking One Liner

This is useful when you're quickly trying to decide between two methods of performing an action.

[1] pry(main)> u = "/foo/bar/"
=> "/foo/bar/"
[2] pry(main)> Benchmark.realtime { u.split("/").join("::") } > Benchmark.realtime { u.gsub("/", "::").gsub(/::$/, "") }
=> false
[3] pry(main)> u.split("/").join("::")
=> "::foo::bar"
[4] pry(main)> u.gsub("/", "::").gsub(/::$/, "")
=> "::foo::bar"

As you can see, the first method u.split("/").join("::") is faster.

Alternatives to OpenStruct

OpenStruct is bad. Here are two quick alternatives.

Published on in Ruby

Thin Wrapper Script

Their may be others, there may be better, but this is mine.

# file: APP_ROOT/thin.sh
#
#!/usr/bin/env bash
# source config if present
test -f ./config/thinrc && source ./config/thinrc

# set up primary defaults
test "$RACK_ENV"  || RACK_ENV="development"
test "$THIN_PORT" || THIN_PORT="4321"
test "$THIN_PID"  || THIN_PID="./log/listener.pid"
test "$THIN_LOG"  || THIN_LOG="./log/listener.log"

test "$DEBUG"     && set -x

if ! test "$1"
then
    echo "Usage: listener start|stop|restart"
    echo " "
    echo "Takes the following overides as environemnt variables:"
    echo " "
    echo "  RACK_ENV  :: default $RACK_ENV"
    echo "  THIN_PORT :: default $THIN_PORT"
    echo "  THIN_PID  :: default $THIN_PID"
    echo "  THIN_LOG  :: default $THIN_LOG"
    echo " "
    echo "Takes config file as './config/thinrc' with overides above. "
    echo " "
    exit 0
fi

RACK_ENV=$RACK_ENV thin --port $THIN_PORT --pid $THIN_PID --log $THIN_LOG --daemonize $1

# vim: set filetype=sh

gist


And if you need external configs...

# file: APP_ROOT/config/thinrc
#
# Directory pathing context should be that of the thin
# init script sourcing this file, not this file itself.
#
# allow for overides as such
test "$RACK_ENV"  || RACK_ENV="production"
test "$THIN_PORT" || THIN_PORT="4321"
test "$THIN_PID"  || THIN_PID="./log/listener.pid"
test "$THIN_LOG"  || THIN_LOG="./log/listener.log"

# force defaults as such
#RACK_ENV="development"
#THIN_PORT="4321"
#THIN_PID="./log/listener.pid"
#THIN_LOG="./log/listener.log"

# vim: set filetype=sh

gist

What is Thin?


Published on in Ruby, Hacks

Rails script/server Unicorn Replacement

A script to replace script/server in Rails, which runs Unicorn over Webrick, because it's faster. This script is designed for development only!

RVM, irb, readline and Ubuntu

It's as easy as:

sudo apt-get install libreadline-gplv2-dev
rvm remove ruby-1.9.3-p194
rvm install ruby-1.9.3-p194

Done.

Notes:

  1. Do not use rvm pkg install readline.
  2. "1.9.3-p194" is an example, should work with most versions.

Published on in Ruby, Linux

Syntax Highlighting on Nesta

I recently went through setting up syntax highlighting on Nesta for this site. I started with "Setting up rack-codehighlighter" from the Nesta site, but wasn't loving what Coderay had to offer. Looking at 'rack-codehighlighter' and it's other formatter options and decided to use Ultraviolet.

While this is geared towards Nesta, this will also work for all Rack applications, especially those built on Sinatra.

Hack: Deploying with git

This has been updated, see: Hack: Deploying with git and rake-remote_remote

Add the following to your Rakefile

ENV['PRODUCTION_HOST'] ||= "www.yourhost.com"
task :deploy do
  system("ssh #{PRODUCTION_HOST} 'set -x; cd /path/to/app/install && git pull && bundle'")
end

desc "restart production" 
task :restart do
  system("ssh #{PRODUCTION_HOST} 'set -x; cd /path/to/app/install && RACK_ENV=#{ENV['RACK_ENV']} bundle exec rake unicorn:restart --trace'")
end

Then run

$ RACK_ENV=production PRODUCTION_HOST=www.foohost.com bundle exec rake deploy restart

or just

$ RACK_ENV=production PRODUCTION_HOST=www.foohost.com bundle exec rake deploy

Note -- This assumes the following:

  • You've checked out your repo on your remote host.
  • You've setup your app and it's running on your remote server.
  • You're using using Unicorn.
  • You're using Bundler.

Hack: Generating gh-pages

With rake

Add the following to your Rakefile

desc "generate and update gh-pages"
task :pages do
  system(" set -x; bundle exec rspec ") or abort
  system(" set -x; bundle exec yardoc --protected ./lib/**/*.rb ") or abort
  system(" set -x; mv -v ./doc /tmp ") or abort
  system(" set -x; mv -v ./coverage /tmp ") or abort
  system(" set -x; git checkout gh-pages ") or abort
  system(" set -x; rm -rf ./doc ./coverage ") or abort
  system(" set -x; mv -v /tmp/doc . ") or abort
  system(" set -x; mv -v /tmp/coverage . ") or abort
  system(" set -x; git add . ") or abort 
  system(" set -x; git commit --all -m 'updating doc and coverage' ") or abort
  system(" set -x; git checkout master ") or abort
  puts "don't forget to run: git push origin gh-pages"
end

Then run

$ bundle exec rake pages
$ git push gh-pages

Or less ugly, with bash...

Create scripts/pages

#!/usr/bin/env bash
set -xue 
bundle exec rspec 
bundle exec yardoc --protected ./lib/**/*.rb
mv -v ./doc /tmp 
mv -v ./coverage /tmp 
git checkout gh-pages
rm -rf ./doc ./coverage 
mv -v /tmp/doc .
mv -v /tmp/coverage . 
git add .
git commit --all -m 'updating doc and coverage'
git checkout master
echo "don't forget to run: git push origin gh-pages"

Then run

$ chmod 755 ./scripts/pages
$ ./scripts/pages

Note -- I opted for the rake method because I use rake in my projects.

Executing BASH from Ruby

Found this today and thought I would share...

Published on in Ruby, Bash

httperf-0.9.1 with individual connection times

This past weekend I dabbled in C++ for the first time patching httperf to use display each connection's timing when using verbose mode.

Automating Performance Testing with httperfrb

Here I'm going to cover basic usage for httperfrb, which I wrote to assist in automating performance testing with httperf. It's important to note that it is designed as an interface to httperf and not a full feature automation suite.

Performance Testing with Httperf

"Httperf -- a tool for measuring web server performance. It provides a flexible facility for generating various HTTP workloads and for measuring server performance. The focus of httperf is not on implementing one particular benchmark but on providing a robust, high-performance tool that facilitates the construction of both micro- and macro-level benchmarks. The three distinguishing characteristics of httperf are its robustness, which includes the ability to generate and sustain server overload, support for the HTTP/1.1 and SSL protocols, and its extensibility to new workload generators and performance measurements."

Benchmarking in Ruby

Benchmark (per Dictionary.com) - "an established point of reference against which computers or programs can be measured in tests comparing their performance, reliability, etc."
In my recent work with caches, I've been making sure to benchmark my code before releasing it. It's pretty evident, that anyone working with caches cares about speed and for larger sites, every millisecond (and sometimes even microsecond) can count.

Published on in Ruby

Duality: Two Caches at Once

Duality is a simple cache helper for using multiple caches. The idea is that you have local cache and a shared cache -- or fast and slow cache -- and want to save to both, and read from local, if present and shared if not. The idea came from Hector Virgen (the PHP Zend Jedi Ninja Badass) and Zend_Cache_Backend_TwoLevels, which does basically the same thing in PHP.

Published on in Ruby

Mongocached: Simple Cache using Mongodb

I created Mongocached, with help from Hector Virgen, as a simple shared cacheing layer for things like html fragments and database calls as a follow up to Diskcached. It specifically targets situations where you want to cache large amounts of data and have memory constraints.

Published on in Ruby

Diskcached: Simple Disk Cacheing for Ruby

I created Diskcached as a simple cacheing layer for things like html fragments and database calls. I thought about using memcached, but as Ditty is running on a single server, it seemed overkill. Additionally, I looked at using rack-cache, but I felt it was a bit more complex then I was looking for. So Diskcached was born (although it was origiionally released as "simple_disk_cache" -- for about 12 hours).

Setting up NewRelic on Sinatra

This week I spent some time setting a NewRelic application on a Sinatra app. It actually turned out to be so simple that I almost hesitate to do a post on it, but hey, here it is any way.

Migrating from MongoMapper to Mongoid

I recently took on the task of migrating Ditty from MongoMapper to Mongoid and it actually wasn't that hard. Fortunately my test suite was adequate enough to catch most of the differences.

Published on in Ruby

Caching external HTTP requests with VCR in Rack

I was recently working on a project to build continuous integration performance tests on an application which makes extensive HTTP based calls to a middleware application. I was running in to issues where the middleware calls were unstable in the test, stage and load test environments. For the purpose of these tests, I was only interested in the render times of the Rails calls. The obvious choice seemed to cache the external HTTP requests.

MongoMapper: Overwriting a Collection Name

I found this very hard to find online, so I'm dropping a post in here with it. To overwrite a collection name when using MongoMapper build your model like so:

require 'mongomapper'
class Collection
  include MongoMapper::Document
  # default collection name is "collections" which
  # looks for 'db.collections' in mongo.

  set_collection_name "some_collections"
  # new collection name is "some_collections" which
  # looks for 'db.some_collections' in mongo.

  key :some_data, String

end 

Published on in Ruby

Killing whitespace in HAML

HAML really like's to drop tag elements to the next line and personally, I find it a total pain. The HAML REFERENCE has some examples removing whitespace, but through trial and error I was able to find a few edge-cases that weren't mentioned.

Published on in Ruby

vlad-push

Vlad is a simple Rake based deployment tool, similar to Capistrano, which allows for easily managing code deployments on multiple servers and various environments. I'm not going to take a deep dive in to Vlad here and now, but you can learn more about it here.

HAML link trailing whitespace sucks!

I was having issues with whitespace at the end of links whose text is being populated by a variable, example:

%a{ :href => "/foo" }
  =my_foo

Was resulting in:

<a href="/foo">
    My Foo
</a>

To fix this, I was able to do this...

%a{ :href => "/foo" } #{my_foo}

Resulting in:

<a href="/foo">My Foo</a>

Ta-Dah!!

Published on in Ruby

Configurable Template Engine in Sinatra

A lot of people have taken to using HAML, example "sinatra-authentication" uses it by default. I personally don't like it, but I don't judge either. So that said, I wish that more apps out there would steer away from implicitly defining haml calls in their apps. Here's an easy way to allow the template engine to be configurable in Sinatra

Sinatra Mobile Dection - rack-mobile-detect

I was looking for a simple way to detect mobile devices for this blog, a Sinatra application, and found rack-mobile-detect.

Deploy Sinatra with Vlad and Git

Deploying Sinatra with Vlad the Deployer and Git is basically just deploying with Vlad.

Sourcing and Setting Environment Variables in Ruby

I was looking for a simple way to source and set a bash environment variable from a file, in this specific instance, I can't be 100% sure that the any steps I take to ensure that the file itself is sourced on the host before Rails is started, nor can I impact the format of the file itself (e.g. changing it to YAML).

Published on in Ruby, Bash

Dynamically Generated Object with Accessors

I was working on created a super class for use in importing various unknown data types from hashs, so I started playing around with dynamic instance variable and attr_accessor generation and came up with the following, which I thought I would share.

Published on in Ruby

Mocking HTTP Response body for rSpec

I'm sure there are many ways to do this -- probably better ways -- but this is a simple way I've done it.

class FakeResponse
  attr :body
  def initialize body
    @body = body
  end
end

describe Foo do
  before(:each) do
    @data = File.read "./http/response/body.txt"
    Net::HTTP.stub!(:post_form).and_return(FakeResponse.new @data)
  end
  it "should return stuff" do
    Foo.fetch( :key => "foo", :uri => "http://foobar.com/" ).should eq(@data)
  end
end

Note:

Since originally coming up with this, I found VCR, check it out, it does this type of thing in some very cool ways.

Published on in Ruby

How-to: Setup MySQL and RoR on AWS

I have been working on setting up RoR with MySQL on an AWS instance and ran in to some oddities, so I decided to document the steps I took and lay it all out real nice and pretty.