我正在编写一个简单的脚本,从debian网站获取一些软件包的详细信息。在处理没有与之关联的版本的虚拟软件包时遇到问题。
我收到以下错误消息
undefined method `first' for nil:NilClass (NoMethodError)
罪魁祸首是
version = doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last.first
我试图将它放入if条件中,但这样做不起作用。
if doc.css('#content h1').text
version = doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last.first
end
所以我想知道如何检查对象是否为零,然后尝试从中提取子字符串。
这是包含除非块
的整个脚本require 'rubygems'
require 'nokogiri'
require 'open-uri'
# additional code to make sure that we can resume after a break seamlessly
last_package = 0
File.open('lastbreak','r') { |fptr| last_package = fptr.gets.to_i }
puts "Resuming from package:#{last_package}" if last_package != 0
# to read each package from packageslist.txt and fetch the required info
# also to store this into a file that can easily be read by the c++ program
BASE_URL = "http://packages.debian.org/stable/"
File.open('packages_list.txt','r') do | fptr |
while line = fptr.gets
package_id = line.split[0].to_i
package = line.split[1]
dependencies = ""
url = BASE_URL + package
if package_id >= last_package
doc = doc = Nokogiri::HTML(open(url))
doc.css(".uldep a").each do |dependency|
dependencies << dependency.text + ","
end
dependencies = dependencies.split(',').uniq.join(',')
description = doc.css('#pdesc').text.strip
version = ""
unless doc.css('#content h1').nil?
version = doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last.first
end
File.open("packages/#{package}","w") do |wfptr|
wfptr.puts "PackageId:#{package_id}"
wfptr.puts "Name:#{package}"
wfptr.puts "Version:#{version}"
wfptr.puts "Deps:#{dependencies}"
end
File.open("packages/#{package}.description",'w') {|wf| wf.write(description.capitalize)}
package_id += 1
puts "Now Processing #{package_id}"
File.open('lastbreak','w') { |fptr| fptr.puts "#{package_id}" }
end
end
end
现在错误信息是
/Users/ccuser008/Documents/oops_project/repo/repobuilder.rb:30:in `block': undefined method `first' for nil:NilClass (NoMethodError)
from /Users/ccuser008/Documents/oops_project/repo/repobuilder.rb:15:in `<main>'
答案 0 :(得分:9)
Ruby 2.3.0添加了一个安全导航操作符(foo&.bar
),在调用方法之前检查nil。
nil
如果foo
为nil
,则会返回NoMethodError
,而非提出$("document").ready(function() {
$('#remove_cv').click(removeCV);
});
function completeHandler(event){
var response = JSON.parse(event.target.responseText);
$('#remove_cv').removeAttr('disabled').attr('data-id', response.document_id);
console.log($('#remove_cv').attr('data-id'));
}
function removeCV(){
var document_id = $(this).data('id');
// Fire Ajax call to delete the document
$.ajax({
type: 'DELETE',
url: getDomain() + 'documents/' + document_id,
dataType: 'json',
cache: false,
success: function(data, textStatus){
$('#remove_cv').attr('disabled', 'disabled');
}
});
}
。
答案 1 :(得分:2)
取决于doc.css('#content h1')
或doc.css('#content h1').text
或doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last
示例 -
unless doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last.nil?
version = doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last.first
end
您可以在unless子句中包含适当的条件。
从您的例外doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last
似乎是零。所以你可以检查一下。
答案 2 :(得分:2)
你用过试试吗?
像
这样的东西doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last.try(:first)
如果您在项目中包含active_support或者您正在使用Rails应用程序,这将有效。
查找“try”方法的语法和文档。
更新:
x = doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last
version = x.first if !x.nil? # why bother.
仅供参考:我知道这并不适用于您的问题,但是如果将这些方法链接起来而不检查其间的null,则可能非常难以与输入的文档结构耦合。如果.css(“#content h1”)。text为null?
答案 3 :(得分:-1)
使用
try(method, *args, &block)
在你的情况下:
doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last.try(:first)
有关详细信息,请参阅:
http://www.intridea.com/blog/2010/11/2/calling-methods-on-potential-nil-objects-in-rails