哈希的未定义方法`to_i'

时间:2013-03-23 00:48:08

标签: ruby rubygems sinatra rack

我正在为我的Rack应用程序创建一个子域路由器,但我遇到了一个问题。这是我的config.ru代码:

require './controllers/subdomain'
require './controllers/www'

set :root, './'

run Example::Subdomain.new({
                                :www => Sinatra::Application
                            })

这是我的subdomain.rb代码:

module Example
  class Subdomain
    def initialize(map = {})
      @map = map
    end

    def call(env)
      @map.each do |subdomain, app|
        if env['HTTP_HOST'].split('.').first.eql?(subdomain)
          app.call(env)
        end
      end
    end
  end
end

当我运行时,我收到以下错误:

NoMethodError: undefined method `to_i' for {:www=>Sinatra::Application}:Hash
  /Library/Ruby/Gems/1.8/gems/rack-1.5.2/lib/rack/lint.rb:555:in `check_status'
  /Library/Ruby/Gems/1.8/gems/rack-1.5.2/lib/rack/lint.rb:19:in `call'
  /Library/Ruby/Gems/1.8/gems/rack-1.5.2/lib/rack/lint.rb:19:in `assert'
  /Library/Ruby/Gems/1.8/gems/rack-1.5.2/lib/rack/lint.rb:555:in `check_status'
  /Library/Ruby/Gems/1.8/gems/rack-1.5.2/lib/rack/lint.rb:51:in `_call'
  /Library/Ruby/Gems/1.8/gems/rack-1.5.2/lib/rack/lint.rb:37:in `call'
  /Library/Ruby/Gems/1.8/gems/rack-1.5.2/lib/rack/showexceptions.rb:24:in `call'
  /Library/Ruby/Gems/1.8/gems/rack-1.5.2/lib/rack/commonlogger.rb:33:in `call_without_check'
  /Library/Ruby/Gems/1.8/gems/sinatra-1.3.6/lib/sinatra/base.rb:161:in `call'
  /Library/Ruby/Gems/1.8/gems/rack-1.5.2/lib/rack/chunked.rb:43:in `call'
  /Library/Ruby/Gems/1.8/gems/rack-1.5.2/lib/rack/content_length.rb:14:in `call'
  /Library/Ruby/Gems/1.8/gems/thin-1.5.0/lib/thin/connection.rb:81:in `pre_process'
  /Library/Ruby/Gems/1.8/gems/thin-1.5.0/lib/thin/connection.rb:79:in `catch'
  /Library/Ruby/Gems/1.8/gems/thin-1.5.0/lib/thin/connection.rb:79:in `pre_process'
  /Library/Ruby/Gems/1.8/gems/thin-1.5.0/lib/thin/connection.rb:54:in `process'
  /Library/Ruby/Gems/1.8/gems/thin-1.5.0/lib/thin/connection.rb:39:in `receive_data'
  /Library/Ruby/Gems/1.8/gems/eventmachine-1.0.3/lib/eventmachine.rb:187:in `run_machine'
  /Library/Ruby/Gems/1.8/gems/eventmachine-1.0.3/lib/eventmachine.rb:187:in `run'
  /Library/Ruby/Gems/1.8/gems/thin-1.5.0/lib/thin/backends/base.rb:63:in `start'
  /Library/Ruby/Gems/1.8/gems/thin-1.5.0/lib/thin/server.rb:159:in `start'
  /Library/Ruby/Gems/1.8/gems/rack-1.5.2/lib/rack/handler/thin.rb:16:in `run'
  /Library/Ruby/Gems/1.8/gems/rack-1.5.2/lib/rack/server.rb:264:in `start'
  /Library/Ruby/Gems/1.8/gems/rack-1.5.2/lib/rack/server.rb:141:in `start'
  /Library/Ruby/Gems/1.8/gems/rack-1.5.2/bin/rackup:4
  /usr/bin/rackup:19:in `load'
  /usr/bin/rackup:19
  -e:1:in `load'
  -e:1

有没有人知道为什么会这样,而不是运行app.call(env)

这是错误的屏幕截图: http://i46.tinypic.com/3538is6.jpg

此代码也有效,但它不遵守子域规则:

module Example
  class Subdomain
    def initialize(map = {})
      @map = map
    end

    def call(env)
      @map.each do |subdomain, app|
        return app.call(env)
      end
    end
  end
end

2 个答案:

答案 0 :(得分:2)

Rack认为您在@map的响应三元组中返回[status, headers, body]状态代码(如here所示)。这是因为each在迭代结束时返回集合,并且这被用作call的返回值。

也许这对你有用,或者至少让你开始:

def call(env)
  subdomain = env['HTTP_HOST'].split('.').first
  app = @map[subdomain]
  app.call(env)
end

答案 1 :(得分:0)

我最终使用以下代码修复此问题:

module Example
  class Subdomain
    def initialize(map = {})
      @map = map
    end

    def call(env)
      @map.each { |subdomain, app| return app.call(env) if env['HTTP_HOST'].split('.').first.eql?(subdomain) }
    end
  end
end

run Example::Subdomain.new({
        'www' => Sinatra::Application,
        'api' => Example::API
    })

我将哈希值更改为包含在''中的字符串,并将return添加到app.call(env)