GurusQ: Metal calling disparity-How to install metal in code

I have a simple class that I want to install as Rails Metal. I don’t
want to put it into a file in app/metal for reasons I don’t want to go
into. It looks like this, and handler is defined elsewhere.

class UrlFilter
ALLOW = [404]
DENY = [403]
def self.call(env)
handler.call(env[“PATH_INFO”]) ? ALLOW : DENY
end
end

I’ve tried installing it like this :
ActionController::Dispatcher.middleware.use UrlFilter

but on the first request it crashes with :

Sat Apr 03 00:29:43 +0800 2010: Read error: #<ArgumentError: wrong
number of arguments (0 for 1)>
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.5/lib/action_controller/middleware_stack.rb:31:in
call' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.5/lib/action_controller/middleware_stack.rb:31:inklass’
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.5/lib/action_controller/middleware_stack.rb:42:in
active?' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.5/lib/action_controller/middleware_stack.rb:112:inactive’
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.5/lib/action_controller/dispatcher.rb:108:in
find_all' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.5/lib/action_controller/middleware_stack.rb:112:ineach’
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.5/lib/action_controller/middleware_stack.rb:112:in
find_all' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.5/lib/action_controller/middleware_stack.rb:112:inactive’
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.5/lib/action_controller/middleware_stack.rb:116:in
build' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.5/lib/action_controller/dispatcher.rb:130:inbuild_middleware_stack’
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.5/lib/action_controller/dispatcher.rb:113:in
call' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.5/lib/action_controller/reloader.rb:34:inrun’
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.5/lib/action_controller/dispatcher.rb:108:in
call' /Library/Ruby/Gems/1.8/gems/rails-2.3.5/lib/rails/rack/static.rb:31:incall’
/Library/Ruby/Gems/1.8/gems/rack-1.0.1/lib/rack/urlmap.rb:46:in call' /Library/Ruby/Gems/1.8/gems/rack-1.0.1/lib/rack/urlmap.rb:40:ineach’
/Library/Ruby/Gems/1.8/gems/rack-1.0.1/lib/rack/urlmap.rb:40:in call' /Library/Ruby/Gems/1.8/gems/rails-2.3.5/lib/rails/rack/log_tailer.rb:17:incall’
/Library/Ruby/Gems/1.8/gems/rack-1.0.1/lib/rack/content_length.rb:13:in
call' /Library/Ruby/Gems/1.8/gems/rack-1.0.1/lib/rack/chunked.rb:15:incall’
/Library/Ruby/Gems/1.8/gems/rack-1.0.1/lib/rack/handler/mongrel.rb:64:in
process' /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:159:inprocess_client’
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in each' /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:inprocess_client’
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in run' /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:ininitialize’
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in new' /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:inrun’
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in
initialize' /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:innew’
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in run' /Library/Ruby/Gems/1.8/gems/rack-1.0.1/lib/rack/handler/mongrel.rb:34:inrun’
/Library/Ruby/Gems/1.8/gems/rails-2.3.5/lib/commands/server.rb:111
/Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in
gem_original_require' /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:inrequire’
script/server:3

The rails calling code looks like this :

  def klass
    if @klass.respond_to?(:call)
      @klass.call
    elsif @klass.is_a?(Class)
      @klass
    else
      @klass.to_s.constantize
    end
  rescue NameError
    @klass
  end

  def active?
    return false unless klass

    if @conditional.respond_to?(:call)
      @conditional.call
    else
      @conditional
    end
  end

Notice when calling call no arguments are passed (twice!) ? Every metal
example I’ve seen defines the entry method as

def self.call(env)

yet this calling code doesn’t pass any.

Whats going on ? How do I define and install a metal class in code ?