当前位置: 首页 > 知识库问答 >
问题:

Ruby错误:nil的未定义方法'[]':NilClass

东方建修
2023-03-14

我正在学习Ruby,我有一个无法理解的bug。我有一个方法,它接受一个字符串(行)数组,并删除所有行,直到包含模式的某一行。该方法如下所示:

def removeHeaderLines(lines)
  pattern = "..." # Some pattern.

  # If the pattern is not there, do not drop any lines.
  prefix  = lines.take_while {|line| (not line.match(pattern))}
  if prefix.length == lines.length then
    return prefix
  end

  # The pattern is there: remove all line preceding it, as well as the line
  # containing it.
  suffix  = (lines.drop_while {|line| (not line.match(pattern))}).drop(1)
  return suffix
end

这工作正常,生成的字符串(行)正确显示在我正在生成的网页上。

此外,我想删除该模式后面的所有非空行。我修改了方法如下:

def removeHeaderLines(lines)
  pattern = "..." # Some pattern.

  # If the pattern is not there, do not drop any lines.
  prefix  = lines.take_while {|line| (not line.match(pattern))}
  if prefix.length == lines.length then
    return prefix
  end

  # The pattern is there: remove all line preceding it, as well as the line
  # containing it.
  suffix  = (lines.drop_while {|line| (not line.match(pattern))}).drop(1)

  # Remove leading non-empty lines.
  # ADDING THIS INTRODUCES A BUG.
  body = suffix.drop_while {|line| (line != "")}
  return body
end

令人惊讶的是(至少对我来说)这不起作用。在生成的网页上,我看到的不是内容,而是错误html" target="_blank">消息:Liquid error:nil类的未定义方法“[]”。

我无法理解这个消息。据我所知,一些调用我的代码的代码试图访问一个非数组对象,就像它是一个数组一样。但是我的方法的两个版本都返回一个字符串数组(变量后缀和body都设置为字符串数组),那么为什么会有区别呢?

因此,不幸的是,同样由于我对Ruby的知识匮乏,我不知道如何调试这个问题。

有人看到上面的代码有错误吗?或者,有没有人对什么会导致nil:NilClass的错误“未定义方法”[]”有任何提示?

编辑

其他信息。我正在扩展我自己没有编写的代码(它来自Octopress,file plugins/include_code.rb)。原始渲染代码如下所示:

def render(context)
  code_dir = (context.registers[:site].config['code_dir'].sub(/^\//,'') || 'downloads/code')
  code_path = (Pathname.new(context.registers[:site].source) + code_dir).expand_path
  file = code_path + @file

  if File.symlink?(code_path)
    return "Code directory '#{code_path}' cannot be a symlink"
  end

  unless file.file?
    return "File #{file} could not be found"
  end

  Dir.chdir(code_path) do

    ##################################
    # I have replaced the line below #
    ##################################
    code = file.read

    @filetype = file.extname.sub('.','') if @filetype.nil?
    title = @title ? "#{@title} (#{file.basename})" : file.basename
    url = "/#{code_dir}/#{@file}"
    source = "<figure class='code'><figcaption><span>#{title}</span> <a href='#{url}'>download</a></figcaption>\n"
    source += " #{highlight(code, @filetype)}</figure>"
    safe_wrap(source)
  end
end

我已经更换了线路

code = file.read

code = linesToString(removeHeaderLines(stringToLines(file.read)))

其中缺少的两种方法是:

def stringToLines(string)
  ar = Array.new
  string.each_line {|line| ar.push(line)}

  return ar
end

def linesToString(lines)
  s = ""
  lines.each {|line| s.concat(line)}

  return s
end

我希望这能有所帮助。

编辑2

感谢哈桑的提示(使用连接方法),我发现了问题!与连接方法并行的还有一个拆分方法。所以

"A\nB\n".split(/\n/)

给予

["A", "B"]

然而,通过使用每一行(正如我所做的那样),我们可以得到每一行的末尾都有“\n”。因此

suffix.drop_while {|line| (line != "")}

删除所有行。结果是一个空字符串显然使我使用的库崩溃。感谢哈桑提出了一个更为惯用的解决方案。我现在有以下内容:

def removeHeaderLines(code)
  lines = code.split(/\r?\n/)
  pat   = /.../ # Some pattern.
  index = lines.index {|line| line =~ pat}
  lines = lines.drop(index + 1).drop_while {|line| line != ""} unless index.nil?

  lines.join "\n"
end

而且效果很好。

共有2个答案

公冶弘壮
2023-03-14

我不知道是什么原因导致异常,但您的代码可能是这样的:

def remove_header_lines(lines)
  pattern = /some pat/
  index = lines.index {|lines| lines =~ pattern}

  lines = lines.drop(index+1).drop_while {|lines| line != ""} unless index.nil?

  lines.join
end
熊锐进
2023-03-14

当您尝试将nil用作数组(或哈希)时,会发生该异常

irb(main):001:0> nil[0]
NoMethodError: undefined method `[]' for nil:NilClass
        from (irb):1
        from /home/mslade/rubygems1.9/bin/irb:12:in `<main>'

或在未初始化时将变量用作数组(或哈希):

irb(main):005:0> @b[0]
NoMethodError: undefined method `[]' for nil:NilClass
        from (irb):5
        from /home/mslade/rubygems1.9/bin/irb:12:in `<main>'

查找您忽略初始化数组的位置,使用@b = []

如果您实际上没有使用数组,那么您调用的函数可能需要一个数组。从顶部开始扫描给定的stak转储,直到它提到您的代码行。然后调查该行,看看您可能错过了什么。

 类似资料:
  • 我想用ruby制作一个康威的生活游戏版本。我创建了一个网格类,其中@play\u area作为实例变量。然而,当我运行代码时,@play\u area在经过两次求值后显示为nil(当在行中求值时,如果@play\u area[x\u mod][y\u mod].alive)。为什么会这样? 编辑 以下是初始化函数: 以下是发生错误的函数: 对@play_area中每个单元格的检查显示每个单元格都正

  • Rails关联的基本问题如下表: 商店:名称,网络 产品:标题、价格、店铺id 关系定义为has_many并属于: 型号: shop.rb 产品rb型 控制器: shops\u控制器。rb型 products_controller.rb 在商店视图中,我设法参考并显示每个商店的所有产品,没有问题: 但另一方面,在产品视图中,我无法从Shop表中显示网络信息: 这将返回以下错误:

  • 我知道有很多类似的问题,但这些解决方案都不管用。我有一个关系数据库。具体来说,我有两个相互关联的表格:程序和讲师。 表之间的关系如下: 一个程序“has_many:讲师”和一个讲师“belongs_to:程序” 以下是表格模型的代码: 我还有一个非常简单的观点: 控制器为: 问题是RoR没有识别表之间的关系,导致行"@an.instructors.empty?失败,并出现以下错误:nil的未定义方

  • 我用最新的Mac OS版本M1在MacBook Air上运行可可豆。我的问题是:当我运行时,我会得到以下输出(我会删除一点,因为其他方式会很长): nil的未定义方法“map”:NilClass 完全错误: LoadError-dlopen(/Library/Ruby/Gems/2.6.0/Gems/ffi-1.15.0/lib/ffi_c.bundle,9):未找到合适的图像。确实找到了:/Li

  • 大家好,我正在尝试运行我的第一个ror应用程序,并出现以下错误: 所以我写: 最后: 如你所见,我正在使用windows。Windows 8 32位。 我找到了这个答案:在这里输入链接描述 还有别的办法吗?