The State of Ruby's send Method

Posted by paul
on 17 November 2008

Calling a method in Ruby can be thought of as sending a message to an object. This isn't just an abstract concept, it's actually implemented in the language by the send method.

'foo'.length
# => 3
'foo'.send :length
# => 3

This is a really important method in Ruby (often used in meta-programming), so important in fact, that just in case you accidentally overwrite send in your own code, it is aliased as __send__ to make sure it can always be called.

One aspect of send that often causes discussion1 is the fact that it allows you to call private methods which would otherwise be inaccessible using the regular method calling syntax, for example:

class Foo
  private
  def bar
    'baz'
  end
end

foo = Foo.new

foo.bar
# => NoMethodError: private method `bar' called for #<Foo:0x118fcbc>

foo.send :bar
# => "baz"

And for a while, Ruby 1.9 changed the implementation of send to only allow public methods to be called, introducing a new send! method2 which continued to allow private methods to be called. However, this has now been removed from Ruby 1.9 in favour of keeping the functionality of send as is. Instead, a new public_send method has been introduced which as you might expect will only call public methods.

  1. There are probably others threads, but the send bang method was discussed on the Ruby Talk mailing list.
  2. For forward compatability with Ruby 1.9 send was aliased as send! in Rails as well, although this has also since been removed.

Shoes and Arduino Etch a Sketch

Posted by paul
on 18 August 2008

Here's a short video of me struggling to demo an Etch a Sketch app which formed part of a presentation I gave at BarCamp Leeds as part of Simon Wheatley's 'My Last Project' session.

The code is a bit rough in places but might be of interest if like me you're getting started with either Arduino or Shoes development.

An include_any Matcher for RSpec

Posted by paul
on 29 June 2008

Writing custom RSpec expectation matchers is a great way to enhance the readability of your specifications. As an example, here's a simple matcher to check whether a collection contains any of the given items. An example will make things clearer:

# Passing example
odds  = [1,3,5,7,9]
evens = [2,4,6,8]
odds.should_not include_any(*evens)

One thing to note is that include_any expects multiple arguments rather than a collection, hence the splat. Here's the code:

module Spec
  module Matchers
    def include_any(*args)
      IncludeAny.new(*args)
    end
  
    class IncludeAny
      def initialize(*args)
        @args = args
      end
    
      def matches?(target)
        @target = target
        @target.include_any?(*@args)
      end
    
      def failure_message
        "expected #{@target.inspect} to include one or more elements from #{@args.inspect}"
      end
    
      def negative_failure_message
        "expected #{@target.inspect} not to include any elements from #{@args.inspect}"
      end
    end
  end
end

This is about as trivial as a custom matcher gets. All of the work is done by the include_any? method, which doesn't actually exist as part of the core Ruby API. In fact it's a simple extension to Enumerable that I think I originally borrowed from Merb. Put the following in config/initializers/core_extensions.rb or similar to use it in a Rails app.

module Enumerable
  def include_any?(*args)
    args.any? { |arg| self.include?(arg) }
  end
end

Which custom matchers are you using?