Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby how to call a method only when the object is not nil

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>'
like image 218
nikhil Avatar asked Oct 17 '11 07:10

nikhil


People also ask

How do you check if something is not nil in Ruby?

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).

Is nil the same as null Ruby?

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.

Is nil an object in Ruby?

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.


1 Answers

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.

like image 164
user513951 Avatar answered Nov 07 '22 15:11

user513951