1

I have absolutely no experience in Ruby, but am trying to debug an issue in FPM. Sometimes, when running FPM, I get the following stack trace:

output': undefined method `empty?' for nil:NilClass (NoMethodError)

I traced this error back to this line (rpm.rb, line 419):

if @epoch.nil? or @epoch.empty?
   @logger.warn("no value for epoch is set, defaulting to nil")
   return nil
end

This blog post says the following about the or operator:

The best way to think about the chains constructed with or is as series of fallbacks: try this, if that fails try this, and so on

This leads me to believe that in the above code fragment, if epoch.nil? evaluates to true, it will not attempt to check epoch.empty?, but a simple codepad shows that to be wrong (http://codepad.org/qI7rLvBX)

str = nil
puts str.nil? or str.empty?

Output:
Line 2: undefined method `empty?' for nil:NilClass (NoMethodError)
true

if I change it the operator to ||, then the short-circuiting works correctly - if epoch.nil? evaluates to true, it does not attempt to evaluate epoch.empty?.

Am I misunderstanding something about the or operator? And is the way FPM is checking for nil or empty incorrect?

Ayush
  • 41,754
  • 51
  • 164
  • 239
  • what ruby version are you using? – Green Su May 20 '14 at 05:36
  • Also tried for 1.8.7. Didn't get error for `if @epoch.nil? or @epoch.empty?`. And logically, this line should not raise error, as `if` has lower precedence than `or`. See http://codepad.org/JTacEmoj – Green Su May 20 '14 at 05:44

2 Answers2

3

You could skip the whole problem by noting that nil.to_s is an empty string:

NilClass#to_s → ""

Always returns the empty string.

Given that, you could say:

if @epoch.to_s.empty?

This is a useful trick for avoiding a bunch of noisy nil? tests when dealing with strings.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
2

It's a matter of operator precedence. || has a higher precedence than or. You should write it like:

str = nil
puts (str.nil? or str.empty?)
puts str.nil? || str.empty?

See more in Difference between "or" and || in Ruby?

For the issue of FPM, I have tried under Ruby 1.8.6, 1.9.3, 2.0.0, and did not get error with or expression.

Community
  • 1
  • 1
Green Su
  • 2,318
  • 2
  • 22
  • 16
  • Adding the parenthesis fixes the issue - so then, as you said, the issue is only in my codepad because `puts` has a higher precedence than `or`, but not in FPM since `if` has a lower precedence than `or`. Thanks for clarifying that. – Ayush May 20 '14 at 05:46