What is a better way to check for a nil object before calling a method on it?
Personally, I would use the or
operator/keyword:
(financial_document.assets or []).length
Either way, .length
is called on an array, giving you 0
if nil
.
Ruby how to call a method only when the object is not nil
Depends what is being returned nil doc.css('#content h1')
or doc.css('#content h1').text
or doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last
Example -
unless doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last.nil?
version = doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last.first
end
you can include the proper condition in the unless clause.
From your exception doc.css('#content h1').text.strip.scan( /\(([^>]*)\)/).last
seems to be nil. So you can check on this.
Checking if a variable is not nil and not zero in ruby
unless discount.nil? || discount == 0
# ...
end
Ruby: check if object is nil
You seem to have a few questions here, so I'll take a stab at what seems to be the main one:
If you want to see if something is nil, just use .nil?
- so in your example, you can just say request.nil?
, which returns true
if it is nil
and false
otherwise.
Check if a method/property is defined or not before calling
If there is a config.user
defined in every environment, but sometimes it has a value, and sometimes it doesn't, for example, it could be nil
or an empty string, you can use present?:
Rails.application.config.user.present?
If it is not defined, you will get a NoMethodError
in the case above, so you can rescue it:
begin
user_name = Rails.application.config.user.present? ? Rails.application.config.user : 'some_other_value'
rescue NoMethodError
user_name = 'some_other_value'
end
respond_to?
should also work, just make sure you don't confuse it with respond_to
, which is a Rails method. It might look something like this:
if Rails.application.config.respond_to?(:user) && Rails.application.config.user.present?
user_name = Rails.application.config.user
else
user_name = 'some_other_value'
end
Nil when calling a method on the variable, but not nil when calling just the variable
Your initialize method assigning @value = value
calls the function at def value
which returns @nums
which has not yet been created in initialize since @nums is created afterwards with nums ||= []; @nums = nums
therefore it's nil. This is why .pop won't work.
You've created @nums as an array with nums ||= []
and you're using it with push and pop so why are you checking for the value with value.should == 5 (Integer) when calling value
returns an (Array). You would need to write it like value.first.should == 5 or value[0].should == 5 ... otherwise you should change value to return just the element you want
def value
@nums.pop # or @nums[0], or @nums.first or @nums.last however you plan on using it
end
The problem is @value = value in your initialize method. Fix that then you can add the .pop in value.
EDIT
Also your evaluation is calling methods before you've populated @nums with the values. Then the methods "raise" errors. You can't call minus after only one value has been pushed to @nums.
Here's how I would do the flow for splitting the string
# Multiplication and Division need to happen before addition and subtraction
mylist = "1+3*7".split(/([+|-])/)
=> ["1", "+", "3*7"]
# Compute multiplication and division
mylist = mylist.map {|x| !!(x =~ /[*|\/]/) ? eval(x) : x }
=> ["1", "+", 21]
# Do the rest of the addition
eval mylist.join
=> 22
I realize this isn't exactly how you're going about solving this... but I think splitting by order of mathematical sequence will be the right way to go. So first evaluate everything between (), then only multiplication and division, then all addition and subtraction.
EDIT I just looked into what a RPN Calculator is. So don't mind my splitting recommendation as it doesn't apply.
Checking if Nokogiri object is nil before accessing text method
You can use "try" for those cases
fiber = doc.xpath("/*[name()='food']/*[name()='servings']/*
[name()='serving']/*[name()='fiber']").first.try(:text)
It returns nil if first is nil, and it calles text if it's not nil
If you need a default value in case it's nil you can do
fiber = doc.xpath("/*[name()='food']/*[name()='servings']/*
[name()='serving']/*[name()='fiber']").first.try(:text) or 'default'
Related Topics
How to Save Unescaped & in Nokogiri Xml
Is Every Relavant Calculation Performed Every Time the Page Is Loaded
Replacing Text in One CSV Column Using Fastercsv
How to Export Environment Variable Permanently Using Ruby
How to Ruby on Rails Authentication with Ldap
How to Use Ruby for Shell Scripting
Rmagick Installation: Can't Find Magickwand.H
Checking If a Variable Is Not Nil and Not Zero in Ruby
Ruby Array to String Conversion
Link_To Method and Click Event in Rails
Ruby: How to Load a File into Interactive Ruby Console (Irb)
Remove Substring from the String
How to Use Ruby Regexp to Substitute String with a "Callback Function"-Like Manipulation
Ruby Float#Round Method Behaves Incorrectly with Round(2)
Unknown Ruby Interpreter Version (Do Not Know How to Handle): Ruby_Version