Posts Tagged ‘ruby’

env: ruby_bundler_wrapper: No such file or directory

Thursday, September 20th, 2012

I spent bunch of time scratching my head, trying to figure out why my ruby executables (rails, heroku, etc) weren’t working. I thought it was because I had an old custom shebang in my .gemrc, but that didn’t seem to change anything. I ran gem regenerate binstubs and that didn’t help either. I still to this day don’t even know what package provides ruby_bundler_wrapper, or even where it lives.

BUT, I figured out the problem for me was that I had my gems stored in a global rvm gemset, so I had to regenerate the binstubs in there:

rvm @global do rvm regenerate binstubs

And that seemed to do the trick. Long morning of system administration today.

Quoting quotes in Ruby

Thursday, June 21st, 2012

Cucumber makes heavy use of quotes to wrap data:

When I purchase "Oryx and Crake"
Then I should receive an email with the subject "Thank you for your purchase!"

I sometimes need to to programmatically generate these strings, when invoking steps-within-steps:

When /^I purchase "([^""]*)"$/ do |title|
  step "Search for \"#{title}\""
  ...
end

Thankfully, Ruby has a metric shit ton of ways to quote strings. But what I haven’t seen mention of is the fact that you can just use the % operator with an arbitrary character to get a fully interpolated string:

# These are all equivalent:
step %~Search for "#{title}"~
step %(Search for "#{title}")
step %<Search for "#{title}">
# I doesn't matter which symbol you use.  Just use whatever 
# symbol is not present in your string.

All the references I’ve seen tell you to use %Q[whatever] for interpolated strings. The Q seems unnecessary.

But if you want an uninterpolated string you do still need to do %q?whatever?.

Stupid Ruby Tricks 3: Injecting an operator

Friday, June 1st, 2012

Just found out that you can inject an operator into a collection. For example:

[[1,2],[3,4]].inject([], :+)
#=> [1, 2, 3, 4]

You don’t even need the starting value. Rad.

Edit: If you leave out the starting value, injecting an empty array will return nil. Include an empty array as the first parameter if you want an empty array back in that case.

Previous trick: Using find and find_all on ActiveRecord collections

Invoking methods on optional objects

Friday, May 18th, 2012

Lately I’ve been using pretty heavily an extension I wrote to Ruby’s Object class:

# lib/core_extensions/object.rb
class Object
  def defined_and(key=nil)
    return nil if nil?
    block_given? ? yield(self) : self[key]
  end
end

This lets me invoke methods on objects that may or may not exist. It’s really useful for the frequent situations where an optional child object has a method that also applies to it’s parent:

class ZipCode
  def start_for(vegetable)
    planting_specs.for(vegetable).defined_and &:start
  end
end

As opposed to the ugly alternative:

def start_for(vegetable)
  spec = planting_specs.for(vegetable)
  spec.start if spec
end

That will either return a start, or it’ll return nil if no planting_spec was found. It works with a block (&:start is a shortcut for {|x| x.start}) or an enumerable key:

{ :a => 1}.defined_and(:a) #=> 1
nil.defined_and(:a) #=> nil

To use stuff in the lib/core_extensions folder in your Rails app, as defined above, you need an initializer:

# config/initializers/core_extensions.rb
Dir[Rails.root.join("lib/core_extensions/*")].each {|f| require f}

Destructive (low memory) Ruby each

Friday, May 11th, 2012

As mentioned, if you have a loop that allocates a bunch of memory tied to an object, destroying the current object after each iteration can help save on memory. I found myself reusing this pattern, so I just extended Array:

class Array
  def destructive_each
    while item = shift
      yield(item)
    end
  end
end

It’s called “destructive” because after using it your array will be empty.

Using rescue to save on nested ifs

Wednesday, February 22nd, 2012
hash = {
  :a => {:one => 1},
  :b => {:two => 2}
}

I was wanting to write some code that would grab a value from a nested hash like the one above, without knowing whether any of the keys existed, or if even the hash existed. My immediate thought was just to use ifs:

def a1
  if hash && hash[:a]
    hash[:a][:one]
  end
end

That’s a little gnarly with repetition though. So I thought maybe I could just use a rescue:

def a1
  hash[:a][:one]
rescue
end

It certainly reads nicer, and explains the situation more clearly. But using exceptions like this smells a little dangerous. You don’t want to accidentally catch and ignore some other exception. But in this case, where the entire content of the method is just accessing hash values, it seems OK.

I wasn’t sure about performance though. So I wrote a little script to test the two strategies:

def rescuers
  something = {:twelve => 12}
  nothing = nil
  something[:twelve]
  nothing[:twelve]
rescue
end
 
def iffers
  something = {:twelve => 12}
  nothing = nil
  if something
    something[:twelve]
  end
  if nothing
    nothing[:twelve]
  end
end
 
start = Time.now
100000.times do
  rescuers
end
puts "rescuers took #{(Time.now - start)} seconds"
 
start = Time.now
100000.times do
  iffers
end
puts "iffers took #{(Time.now - start)} seconds"

Of course, this is hardly a “natural” benchmark. But it’s better than nothing.

It turns out, on my machine, the rescue strategy is about a factor of 10 slower than the conditional. That’s pretty damning, HOWEVER, you can still do 100,000 rescues in a second. So, unless I’m doing this thousands of time in a web request, it won’t really tip any important scales.

I’m going to go with the rescue for now, and see how I feel about it.

Shift is your friend

Tuesday, February 14th, 2012

This code¹:

crops.each do |c| 
  c.calculate_status(user)
end

takes 0.3 seconds to run. This code:

crops = crops.to_a 
while(c = crops.shift)
  c.calculate_status(user)
end

takes 0.00001 seconds to run. Using shift lets Ruby clear that junk out of memory as soon as you leave the current iteration of your while loop. Each makes you keep it around.

Be advised.

¹ The calculate_status method works looks up some dozens of activerecord objects from different tables and does various calculations amongst them.

Stupid Ruby Tricks: Range to the end of an array

Saturday, February 4th, 2012

Did you know that if you give an array a symbol as the second parameter of a range, and it will just go to the end of the array? Check it out:

array = [1,2,3,4]
array[2,:end] # [3,4]

Any symbol will do, but :end seems like a good choice.

Minimal templating DSL in pure Ruby

Monday, December 12th, 2011

For whatever reason, I felt like working on my metaprogramming brain a little bit last night. So I implemented an as-simple-as-possible templating DSL in pure Ruby. Only 34 lines of code and lets you generate pretty much arbitrary HTML. It ends up being basically a shitty version of Markaby.

Here’s the code and an example:

class Tmpl
  def initialize(tag, *args, &block)
    @tag = tag
    @content = args.find {|a| a.instance_of? String}
    @attributes = args.find{|a| a.instance_of? Hash}
    self.instance_eval &block if block_given?
  end
 
  def to_html
    attr_string = " " << @attributes.map {|k,v| "#{k}=#{v.to_s.inspect}" }.join(" ") if @attributes
    "<#{@tag}#{attr_string}>#{@content}#{children.map &:to_html}</#{@tag}>"
  end
 
  def children
    @children ||= []
  end
 
  # Some of these are Kernel or Object methods or whatever that we need to explicitly override
  [:p, :select].each do |name|  
    define_method name do |*args, &block|
      send :method_missing, name, *args, &block
    end
  end
 
  def method_missing(tag, *args, &block)
    child = Tmpl.new(tag.to_s, *args, &block)
    children << child
    child
  end
 
  def self.method_missing(tag, *args, &block)
    Tmpl.new(tag.to_s, *args, &block)
  end
end
 
 
puts Tmpl.html {
  head do
    title "Hello, World!"
  end
  body do
    h1 "Hi", :class => "foo"
    p "This is an awesome thing. " do
      b "Hot "
      a "Sauce", :href => "/awesome"
    end
    select do
      option "Not me"
      option "There can be only one", :selected => true
    end
  end
}.to_html

Different views for the first element in a list

Friday, December 9th, 2011

On SproutRobot, I’m often showing a calendar and wanting to display this week slightly different than all of the weeks after it. My calendar is just an OrderedHash, with Weeks as keys and then arrays of Events as values. This, with some Ruby and HAML goodness, allows some pretty clean code in the view:

- @weeks.shift.tap do |week, events|
  / do stuff with the first week and it's events here
- @weeks.each do |week, events|
  / and then the rest of the weeks here

On the first line, “shift” pops the first item off of the hash, which is a key-value (week and events) pair. Then “tap” takes that key-value pair and lets me shove it into a block and with attribute names. Then, on the next line the “each” iterates through the remaining items.

I just love how elegantly all of these pieces fit together.