Ruby错误:未定义的方法“[]’;零级:零级
我正在学习Ruby,我有一个我无法理解的bug。我有一个方法,它接受一个字符串数组(行)并删除所有行,直到包含一个模式的某一行。 方法如下所示: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
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?)变量名前面的@是什么意思?数组需要这样做吗?前缀为
@
的变量是实例变量。