Ruby错误:未定义的方法“[]’;零级:零级

Ruby错误:未定义的方法“[]’;零级:零级,ruby,Ruby,我正在学习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(patt

我正在学习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
这很好,结果字符串(行)在网页上正确显示 我在发电

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

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
非常令人惊讶的是(至少对我来说)这不起作用。在生成的网页上,我看到的不是内容,而是错误消息:Liquid error:undefined method`[],用于nil:NilClass

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

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

有人看到上面代码中有错误吗?或者,是否有人对导致nil:NilClass的错误“undefined method`[]”有任何提示

编辑

补充资料。我正在扩展我自己没有编写过的代码(它来自 ,文件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
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

其中缺少的两种方法是:

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

感谢Hassan的提示(使用join方法),我发现了问题! 与join方法并行的还有一个split方法。所以

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

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

suffix.drop_while {|line| (line != "")}
删除所有行。结果是一个空字符串,显然使库崩溃 我正在使用。感谢Hassan指出了一个更为惯用的解决方案。我现在有 以下:

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

当您试图像数组(或散列)一样使用
nil
时,就会出现这种异常:

irb(main):001:0>nil[0]
NoMethodError:nil类的未定义方法“[]”
来自(irb):1
from/home/mslade/rubygems1.9/bin/irb:12:in`'
或在未初始化变量时将其用作数组(或哈希):

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>'
irb(main):005:0>@b[0]
NoMethodError:nil类的未定义方法“[]”
来自(irb):5
from/home/mslade/rubygems1.9/bin/irb:12:in`'
使用类似于
@b=[]


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

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

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
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

如果你可以添加一些你正在处理的文本,那么人们就会告诉你是否有更好的方法来编写你的方法。文本是一个C源文件。在每个源文件的开头,注释中可以有一个可选的GNU许可证。必须删除此许可证注释。此注释的最后第二行包含字符串“www.gnu.org”。因此,我的计划是删除www.gnu.org上的所有前导行,然后删除所有非空行(如*..,*/)。在前导注释结束后,在真正的代码开始之前至少有一行空行。ruby 1.9.2p318(2012-02-14修订版34678)[i686 linux]@DanS:Adding body=[]似乎没有改变任何东西:源代码没有呈现,并且仍然显示错误消息。您是否也可以向我们展示如何将其呈现到网页(liquidmarkup?)变量名前面的@是什么意思?数组需要这样做吗?前缀为
@
的变量是实例变量。