skistaddy
skistaddy

Reputation: 2224

Undefined method <= for false when comparing integers

I have this simple Ruby code that is processing command line arguments:

if !ARGV.length <= 2
    print "clierr: please pass an arg"
end

It is giving me this error message:

client.rb:rb:1:in `<main>': undefined method `<=' for false:FalseClass (NoMethodError)

As far as I know, <= means less than or equal to. And ARGV is the global argument list in Ruby. So why is it erroring?

Upvotes: 2

Views: 221

Answers (2)

Andrew Li
Andrew Li

Reputation: 57924

So why is it erroring?

This is not because ! is a method and you need to call it with parentheses. This is due to operator precedence or order of operations

In Ruby, all integers evaluate to true, the only values that are evaluated to false are false and nil, per the documentation. Now, let's look at your condition:

if !ARG.length <= 2

In this example, ! is the NOT operator. Performing this operation implicitly coerces it into a boolean for boolean operation. And since, as mentioned earlier, ARGV.length is an integer, it is evaluated to true, thus !true is false.

! happens first because ! has higher precedence than <=. After !ARGV.length is evaluated, Ruby then reports that you are trying to do comparison on false and an integer, that's illegal. You have to use grouping to control which operations happen when:

if !(ARGV.length <= 2)

The parentheses will tell Ruby to evaluate the condition inside the parentheses first, then continue evaluating, like order of operations. So, the inside is evaluation, then logical NOT happens.

Upvotes: 2

Tiago Lopo
Tiago Lopo

Reputation: 7959

The right syntax is:

if  !(ARGV.length <= 2)
    print "clierr: please pass an arg"
end

Or you can use unless.

Upvotes: 1

Related Questions