Ruby如何在对象不为nil时调用方法

nik*_*hil 2 ruby methods null undefined

我正在写一个简单的脚本,从debian网站获取一些软件包的细节.在处理没有与之关联的版本的虚拟包时遇到问题.

我收到以下错误消息

undefined method `first' for nil:NilClass (NoMethodError)
Run Code Online (Sandbox Code Playgroud)

罪魁祸首是

version = doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last.first
Run Code Online (Sandbox Code Playgroud)

我试着将它放入if这样的条件,但这不起作用.

if doc.css('#content h1').text 
         version = doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last.first
      end
Run Code Online (Sandbox Code Playgroud)

所以我想知道如何检查对象是否为nil,然后尝试从中提取子字符串.

这是包含except块的整个脚本

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
Run Code Online (Sandbox Code Playgroud)

现在错误信息是

/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>'
Run Code Online (Sandbox Code Playgroud)

use*_*951 9

Ruby 2.3.0添加了一个安全的导航操作符(&.),它在调用方法之前检查nil.

foo&.bar
Run Code Online (Sandbox Code Playgroud)

nil如果foonil,它将返回,而不是提高NoMethodError.


Jay*_*dra 3

取决于返回的内容 nildoc.css('#content h1')doc.css('#content h1').textordoc.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
Run Code Online (Sandbox Code Playgroud)

您可以在 except 子句中包含适当的条件。

从你的例外doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last来看似乎为零。所以你可以检查一下。