I'm writing a simple script, that fetches the details of some packages from the debian website. I encounter a problem when dealing with virtual packages that ave no version no associated with them.
I get the following error message
undefined method `first' for nil:NilClass (NoMethodError)
The culprit line is
version = doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last.first
I tried to put it into an if conditional like this but that doesn't work.
if doc.css('#content h1').text
version = doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last.first
end
So I'd like to know how I can check if the object is not nil and then try to extract the sub-string from it.
Here is the entire script with the unless block added
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
now the error message is
/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>'
In Ruby, you can check if an object is nil, just by calling the nil? on the object... even if the object is nil. That's quite logical if you think about it :) Side note : in Ruby, by convention, every method that ends with a question mark is designed to return a boolean (true or false).
Let's start out with “Nil” since it's the most common and easy-to-understand way of representing nothingness in Ruby. In terms of what it means, Nil is exactly the same thing as null in other languages.
Well, nil is a special Ruby object used to represent an “empty” or “default” value. It's also a “falsy” value, meaning that it behaves like false when used in a conditional statement.
Ruby 2.3.0 added a safe navigation operator (&.
) that checks for nil before calling a method.
foo&.bar
It will return nil
if foo
is nil
, rather than raising NoMethodError
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With