This is a first part of my Ruby Tricks & Quirks serie. I’ll present some non-obvious techniques available in beloved Ruby.

As you probably know in Ruby one can inspect almost everything. Available variables, methods or constants to name a few. But is it possible to check the number of method arguments? Sure it is! Hey, it’s ruby impossible is nothing ;)

The trick is achieved by using arity method.

class Logger

    def log(message)
        $stderr.puts message
    end

end

puts Logger.instance_method(:log).arity # => 1

The most popular use of arity is to check the number of arguments accepted by block.

proc { |a, b, c| a + b + c }.arity # => 3

However now we know that arity applies to methods as well.

Let’s digg deeper and see what does arity return for blocks and variable length of arguments.

class Logger

    def initialize(stream, *args)
        @stram = stream
        @args  = args
        @silent = false
    end
    
    def log(*messages)
        @stream.write messages.join("\n") unless self.silent
    end

    def silence(&block)
        old_silent = @silent
        @silent = true
        yield
    ensure
        @silent = old_silent
    end
end

(Logger.instance_methods - Object.instance_methods).each do |method|
    puts "#{method} takes #{Logger.instance_method(method).arity} arguments"
end

Output of the code above:

    silence takes 0 arguments
    log takes -1 arguments
    initializer takes -2 arguments
  • block doesn’t count as argument so arity of silence equals 0
  • log method has variable length of arguments and it’s arity equals -1
  • if method accepts both mandatory arugments and varaible length of them then
  • arity equals (-1 - NUMBER_OF_MANDATORY_ARGUMENTS). In that case arity of initialize equals -2

WrocLove.rb