(Ruby)错误:`set_encoding':无法在sinatra文件中将String转换为Hash(base.rb,第1760行)

时间:2013-12-12 10:31:03

标签: ruby heroku sinatra sass haml

我正在尝试从github运行示例应用程序。他们的应用运行正常。这意味着我的设置是错误的,但我不知道它是什么。这是我第一次尝试红宝石。

我做了什么:
1-从github下载代码 2-制作了一个gemfile:

source "https://rubygems.org"
ruby "2.0.0"
gem "sinatra", "1.4.4"
gem "haml", "4.0.3"
gem "sass", "3.2.12"

3- ran bundle install
4-当我运行.rb文件(在heroku或我的计算机上)时,我每次都会收到此错误:

/Library/Ruby/Gems/2.0.0/gems/sinatra-1.4.4/lib/sinatra/base.rb:1760:in `set_encoding': can't convert String to Hash (String#to_hash gives Symbol) (TypeError)
    from /Library/Ruby/Gems/2.0.0/gems/sinatra-1.4.4/lib/sinatra/base.rb:1760:in `block in detect_rack_handler'
    from /Library/Ruby/Gems/2.0.0/gems/sinatra-1.4.4/lib/sinatra/base.rb:1758:in `each'
    from /Library/Ruby/Gems/2.0.0/gems/sinatra-1.4.4/lib/sinatra/base.rb:1758:in `detect_rack_handler'
    from /Library/Ruby/Gems/2.0.0/gems/sinatra-1.4.4/lib/sinatra/base.rb:1420:in `run!'
    from /Library/Ruby/Gems/2.0.0/gems/sinatra-1.4.4/lib/sinatra/main.rb:25:in `block in <module:Sinatra>'


- &GT;我应该发出信号,我试图运行的github回购已经过时了(自2010年以来没有被触及)

2 个答案:

答案 0 :(得分:0)

似乎这是使用过的宝石“sinatra”中的一个错误。

尝试更改这样的gemfile(不提供明确的版本号),以便应用程序安装最新版本的gem。

source "https://rubygems.org"
ruby "2.0.0"
gem "sinatra"
gem "haml"
gem "sass"

可能有更新版本的sinatra宝石。

答案 1 :(得分:0)

确定。所以事实证明这不是我的设置。 (我尝试使用2009年的宝石和红宝石版本,并没有让错误消失。)

我通过在脚本中逐渐评论出来缩小范围(因为ruby不会在我自己的文件中给我一行,只在sinatra文件中,我认为起初这不是因为我的代码)。

- &GT;这是一行代码,现在我在我的脚本中对它进行了评论,使错误永远消失,看似没有负面的副作用。 (见下面的代码)。

如果有人可以简单评论一下这个方法(是不是某种sinatra框架回调,对于错误处理对不存在的方法的调用?我假设这个,因为它从未在我的文件中调用过!)以及它为什么会导致错误在问题中描述,我会选择他们的答案,否则我会选择这个(我的)答案。 (只要写下你知道的或者可以找到关于这种方法的任何内容,我会选择你的答案,谢谢)。

def method_missing(methId)
  method_name=methId.id2name.intern
  if @lists.respond_to? method_name
    @lists.send(method_name).pick
  else
    # method_name # line that caused the error in the sinatra source files.
  end
end

=============================================== =

所以这是我自己对method_missing的快速研究......试图在这里学习红宝石:

有关method_missing的一些信息:
http://www.alfajango.com/blog/method_missing-a-rubyists-beautiful-mistress/#/when-to-use-method-missing
http://rubylearning.com/blog/2010/10/07/do-you-know-rubys-chainsaw-method/

第二个链接是一个很棒的介绍。 基本上method_missing是,是一种用于调用不存在的方法的错误处理程序。它是一个ruby语言的东西(它在找不到方法时调用method_missing)。所以它不依赖于框架,只是为了ruby。

除了简单的错误处理之外,它的一个常见用法是能够根据(不存在的)方法名称定义操作(根据不存在的方法名称组成操作!),例如在你有的情况下大量的方法可以做很重复的事情,你可以根据他们的名字来推断/建立他们的行为。

一种限制你的“你将要在当场弥补行为的方法”的方法是使用正则表达式匹配的if(或者在我们的情况下,在预定义的项目列表中匹配) 。如果它不匹配,那么你可以自己抛出一个异常,或者只是返回看看调用代码中接下来会发生什么。

所以在我们的代码中:

if the method name doesnt exist, they check if it exists in a list and act accordingly (they return a list, picked among @lists).
but if it is not found in @lists … they return that very method name, a string, that we didnt have a match for. 

...但现在的问题是: - &gt;调用代码如何处理该返回值? (显然不太好,它似乎期望一个哈希或一个数组,而不是一个方法名称字符串)一种安全的方法来处理“找不到你不存在的方法的匹配”就是调用super,恢复正常执行的调用代码(根据第一个链接)。

所以还有一个问题:返回方法名称是个好主意吗?会返回方法名称吗?或者它真的是错的,超级(或没有)应该放在它的位置?

......我的临时结论是 - &gt;你不应该返回一个列表有时和一些字符串其他时间。所以这是一个明显的错误,令人惊讶的是从来没有引起过问题,或者从未在原始回购中找到过......