Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: Date.today - 1.day

Using the rails console, I just got bit by this:

Assume today is December 11.

Date.today-1.day   # December 10  (no spaces)
Date.today - 1.day # December 10  (a space on both sides of the minus sign)
Date.today -1.day  # December 11  whaaaat?
Date.today -5.days # Still december 11!

Can someone explain what's going on here? I am a little worried about how easy this could be missed in code. Any other suggestions on how to code this?

like image 353
user3092262 Avatar asked Dec 11 '13 17:12

user3092262


2 Answers

The difference you are seeing is caused by the way how ruby parses your code. In your case, you have stumbled about a syntactic nuance which greatly changes how the code is evaluated.

Your first two examples are actually expressions involving an operation on an object. Thus

Date.today-1.day
Date.today - 1.day

are both equivalent to

Date.today.send(:-, 1.day)
# a "fancy" way to write
Date.today - 1.day

Your second two examples

Date.today -1.day
Date.today -5.days

are actually direct method calls on the Date.today method and are thus equivalent to

Date.today( (-1).day )

This is because the minus is interpreted as a prefix to the 1 (and thus is parsed as the number -1). This interpretation is possible and doesn't throw any errors because of two properties of ruby:

  • Parenthesis are optional when calling methods as long as the result is unambiguous
  • Date.today accepts an optional argument denoting calendar used

The actual results you receive depend a bit on your environment as Rails seems to override some Date methods here. In plain Ruby, you would get different dates back but it would still work.

like image 80
Holger Just Avatar answered Oct 29 '22 21:10

Holger Just


When you don't add a space after the minus sign, ruby takes it as a parameter for the function today. This function can receive one parameter. See here

like image 3
davidrac Avatar answered Oct 29 '22 21:10

davidrac