【问题标题】:Ruby giving "NoMethodError: undefined method `[]' for nil:NilClass" with SinatraRuby 使用 Sinatra 给出“NoMethodError: undefined method `[]' for nil:NilClass”
【发布时间】:2014-03-22 17:27:43
【问题描述】:

我是 Ruby 和 Sinatra 的新手,我正在努力学习它们。

这是我的 ruby​​ 代码(文件:ruby_test2.rb)

#!/usr/bin/ruby
require 'rubygems'

class LearnRuby

  def initalize
    @listen = Hash.new { |hash, key| hash[key] = []; }
  end

  def fill_listen(uid, mid)
    @listen[uid]<<=mid
    "In fill_listen #{@listen}\n"
  end

end

这是我的 Sinatra 代码(文件:sinatra_test2.rb)

require 'sinatra'
require './ruby_test2'

if __FILE__ == $0
  lr = LearnRuby.new
end

post '/listen' do
  lr.fill_listen params[:uid] , params[:mid]
end

这就是我运行它的方式。

ruby sinatra_test2.rb

curl --data "uid=u1&amp;mid=m312" http://localhost:4567/listen

当我执行上述操作时,我得到了这个错误(在服务器和客户端(curl)端)

localhost - - [22/Mar/2014:22:54:19 IST] "POST /listen HTTP/1.1" 500 3770
- -> /listen
NoMethodError - undefined method `[]' for nil:NilClass:
    <path>/ruby_test2.rb:11:in `fill_listen'
    sinatra_test2.rb:9:in `block in <main>'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:1593:in `call'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:1593:in `block in compile!'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:957:in `[]'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:957:in `block (3 levels) in route!'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:976:in `route_eval'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:957:in `block (2 levels) in route!'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:997:in `block in process_route'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:995:in `catch'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:995:in `process_route'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:955:in `block in route!'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:954:in `each'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:954:in `route!'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:1067:in `block in dispatch!'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:1049:in `block in invoke'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:1049:in `catch'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:1049:in `invoke'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:1064:in `dispatch!'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:889:in `block in call!'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:1049:in `block in invoke'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:1049:in `catch'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:1049:in `invoke'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:889:in `call!'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:877:in `call'
    /var/lib/gems/1.9.1/gems/rack-protection-1.5.2/lib/rack/protection/xss_header.rb:18:in `call'
    /var/lib/gems/1.9.1/gems/rack-protection-1.5.2/lib/rack/protection/path_traversal.rb:16:in `call'
    /var/lib/gems/1.9.1/gems/rack-protection-1.5.2/lib/rack/protection/json_csrf.rb:18:in `call'
    /var/lib/gems/1.9.1/gems/rack-protection-1.5.2/lib/rack/protection/base.rb:50:in `call'
    /var/lib/gems/1.9.1/gems/rack-protection-1.5.2/lib/rack/protection/base.rb:50:in `call'
    /var/lib/gems/1.9.1/gems/rack-protection-1.5.2/lib/rack/protection/frame_options.rb:31:in `call'
    /var/lib/gems/1.9.1/gems/rack-1.5.2/lib/rack/logger.rb:15:in `call'
    /var/lib/gems/1.9.1/gems/rack-1.5.2/lib/rack/commonlogger.rb:33:in `call'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:217:in `call'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:210:in `call'
    /var/lib/gems/1.9.1/gems/rack-1.5.2/lib/rack/head.rb:11:in `call'
    /var/lib/gems/1.9.1/gems/rack-1.5.2/lib/rack/methodoverride.rb:21:in `call'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/show_exceptions.rb:21:in `call'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:180:in `call'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:2004:in `call'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:1469:in `block in call'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:1778:in `synchronize'
    /var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:1469:in `call'
    /var/lib/gems/1.9.1/gems/rack-1.5.2/lib/rack/handler/webrick.rb:60:in `service'
    /usr/lib/ruby/1.9.1/webrick/httpserver.rb:138:in `service'
    /usr/lib/ruby/1.9.1/webrick/httpserver.rb:94:in `run'
    /usr/lib/ruby/1.9.1/webrick/server.rb:191:in `block in start_thread'
localhost - - [22/Mar/2014:22:54:51 IST] "POST /listen HTTP/1.1" 500 3770

我可能会错过一些小事,但我需要帮助,因为我刚刚开始学习这些技术。

提前致谢。

【问题讨论】:

  • 你能解释一下你想在这行@listen[uid]&lt;&lt;=mid做什么吗?
  • @aakashjain 我需要使用该运算符附加到数组。否则数组会被覆盖并且它总是只包含一个元素。
  • 它不是一个数组,它是一个散列。使用= 运算符将新项目添加到散列中,并且不会被覆盖(除非该键已存在于散列中)。此外,数组的推送运算符是 &lt;&lt; 而不是 &lt;&lt;=

标签: ruby sinatra


【解决方案1】:

这里是你的工作示例,@listen 是 nil,因为你拼错了 initalize -> initialize

require 'sinatra'

class LearnRuby
  def initialize
    @listen = {}
  end

  def fill_listen(uid, mid)
    @listen[uid] = mid
    "In fill_listen #{ @listen }\n"
  end
end

post '/listen' do
  lr = LearnRuby.new
  lr.fill_listen(params[:uid], params[:mid])
end

【讨论】:

  • 非常感谢@Rustam A. Gasanov。啊拼写错误,我花了这么多时间!该死。您建议使用哪个 IDE?我用 vim。
  • 我也在用 vim :)
【解决方案2】:

@listen[uid]&lt;&lt;=mid 替换为@listen[uid] = mid

另外,如果您只需要 initialize 来创建 哈希,那么您可以将 @listen = Hash.new { |hash, key| hash[key] = []; } 替换为 @listen = {}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-19
    • 2016-08-13
    • 1970-01-01
    • 1970-01-01
    • 2016-01-02
    • 2012-08-08
    • 2014-09-05
    • 1970-01-01
    相关资源
    最近更新 更多