Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I do "if zero" in ruby?

Tags:

ruby

>> current_user.first_visit
=> 0
>> if current_user.first_visit
>> puts "test"
>> end
test
=> nil

Why does it print test?

like image 458
Matt Elhotiby Avatar asked Sep 24 '10 03:09

Matt Elhotiby


People also ask

Is 0 true or false in Ruby?

Zero is a value, and ALL values in Ruby are evaluated to true, EXCEPT for FALSE and NIL.

What does 0 mean in Ruby?

string[0] is a new string that contains the first character of string .

How do you check if something is 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).

What does .first mean in Ruby?

The first() is an inbuilt method in Ruby returns an array of first X elements. If X is not mentioned, it returns the first element only. Syntax: range1.first(X) Parameters: The function accepts X which is the number of elements from the beginning. Return Value: It returns an array of first X elements.


2 Answers

In Ruby only nil can be considered as analogue to false. There is no assumption, that 0, "" or [] means false, so you must use == 0, .blank?, .empty?, .zero?, etc.

But nil doesn't always behave as false. For example, in string interpolation, the .to_s method is applied to #{} contents, that works differently for FalseClass and NilClass:

irb(main)> "qwe #{false} rty"
=> "qwe false rty"
irb(main)> "qwe #{nil} rty"
=> "qwe  rty"
like image 84
Nakilon Avatar answered Nov 15 '22 23:11

Nakilon


You can think of Ruby's if as testing either a boolean, or for the availability of data (vs nil). The implicit conversion from 0 to false supported by C and (hence other languages like C++) was more an historical artefact from days before C had a distinct boolean type. There, it relies on 0 being a convenient sentinel value or having an intuitive meaning. For many things (e.g. some country where clothing sizes range from 0 to 8, POSIX libC function call results) zero does not convert nicely to a logically equivalent boolean, so it's not a bad thing that Ruby goes its own way.

From this perspective, the issue with your code is that current_user.first_visit - the name of which implies a boolean type - actually holds 0 and not false. Alternatively, if you had the clearly numeric current_user.visit_counter, it would be natural and correct to use one of:

current_user.visit_counter > 0
current_user.visit_counter >= 1
current_user.visit_counter != 0
like image 43
Tony Delroy Avatar answered Nov 15 '22 23:11

Tony Delroy