我正在学习Ruby,我有一个我无法理解的错误。我有一个方法,它采用一个字符串数组(行)并删除所有行到包含模式的某一行。 该方法如下所示:
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
非常令人惊讶(至少对我而言)这不起作用。在生成的网页上,而不是内容,我看到错误消息:液体错误:未定义的方法`[]'为nil:NilClass。
从这条消息中我无法理解。据我所知,一些调用我的代码的代码试图访问一个非数组对象,就像它是一个数组一样。但两个版本 我的方法返回一个字符串数组(后缀和body都被设置为一个字符串数组),那为什么会有区别呢?
所以,不幸的是,由于我对Ruby的知识匮乏,我不知道如何调试这个问题。
有人在上面的代码中看到任何错误吗?或者,是否有任何人提示任何可能导致错误的错误“未定义的方法`[]'为nil:NilClass”?
修改
其他信息。我正在扩展我自己没有编写的代码(它来自于 Octopress,文件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
感谢Hassan的提示(使用join方法)我发现了问题! 与join方法并行存在split方法。所以
"A\nB\n".split(/\n/)
给出
["A", "B"]
然而,通过使用each_line(就像我所做的那样),最后得到每行的'\ 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
它工作正常。
答案 0 :(得分:1)
当您尝试像数组(或哈希)一样使用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转储,直到它提到你的代码行。然后调查该行,看看你可能错过了什么。
答案 1 :(得分:0)
我不知道导致异常的原因,但您的代码可能是这样的:
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