Project

General

Profile

Bug #11621

Date.- and Date.+ methods inconsistencies

Added by andreionut (Andrei Balcanasu) almost 4 years ago. Updated almost 4 years ago.

Status:
Rejected
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-darwin14]
[ruby-core:71192]

Description

I noticed today some inconsistencies when using - and + methods of the Date class, that makes the whitespace relevant:

irb(main):001:0> require 'date'
=> true
irb(main):002:0> Date.today - 7
=> #<Date: 2015-10-19 ((2457315j,0s,0n),+0s,2299161j)>
irb(main):003:0> Date.today -7
=> #<Date: 2015-10-26 ((2457322j,0s,0n),+0s,2299161j)>
irb(main):004:0> Date.today-7
=> #<Date: 2015-10-19 ((2457315j,0s,0n),+0s,2299161j)>

It looks like the parser ignores the -7 in the context of Date.today instead of interpreting it as 7 days ago

This can be replicated when using integers as variables:

irb(main):002:0> days = 5
=> 5
irb(main):003:0> p (Date.today - days) == (Date.today -days)
false
=> false

or when creating Date with DateTime.now, but weirdly enough not when the Date is in a variable:

irb(main):004:0> now = Date.today
=> #<Date: 2015-10-26 ((2457322j,0s,0n),+0s,2299161j)>
irb(main):005:0> p (now - 7) == (now-7)
true
=> true
irb(main):006:0> p (now -7) == (now-7)
true
=> true

or when creating a Date with the constructors that force you to set a date (new, ordinal, parse, etc)

The other thing that I discovered while testing this was the behaviour to_date when tried to chain the - method:

irb(main):002:0> Time.new(2001,2,3).to_date
=> #<Date: 2001-02-03 ((2451944j,0s,0n),+0s,2299161j)>
irb(main):003:0> Time.new(2001,2,3).to_date -7
ArgumentError: wrong number of arguments (1 for 0)
    from (irb):3:in `to_date'
    from (irb):3
    from /opt/boxen/rbenv/versions/2.2.3/bin/irb:11:in `<main>'
irb(main):004:0> Time.new(2001,2,3).to_date - 7
=> #<Date: 2001-01-27 ((2451937j,0s,0n),+0s,2299161j)>

I've attached a file with my tests and commented the output from my machine.


Files

date.rb (1.41 KB) date.rb andreionut (Andrei Balcanasu), 10/26/2015 03:54 PM

History

Updated by 0x0dea (D.E. Akers) almost 4 years ago

This has nothing to do with Date in particular; observe:

def foo n = nil
  n || 48
end

p foo-6   # => 42
p foo -6  # => -6
p foo - 6 # => 42

This is simply a consequence of parentheses for method invocation being (mostly) optional. The solution is to properly (read: consistently) pad your operators.

Updated by andreionut (Andrei Balcanasu) almost 4 years ago

Good point, but this still does not explain why in some cases -7 works:

now = Date.today
=> #<Date: 2015-10-26 ((2457322j,0s,0n),+0s,2299161j)>
now -7
=> #<Date: 2015-10-19 ((2457315j,0s,0n),+0s,2299161j)>

Date.new(2001,2,3) -7
=> #<Date: 2001-01-27 ((2451937j,0s,0n),+0s,2299161j)>

Updated by 0x0dea (D.E. Akers) almost 4 years ago

Those examples are not ambiguous. Date.today -7 is ambiguous because Date.today takes an optional argument specifying, essentially, which calendar to useā€’one of ITALY, ENGLAND, JULIAN, or GREGORIAN, if you're using the method correctly. As demonstrated earlier, Ruby resolves this ambiguity by assuming you're not trying to trick the parser.

Updated by shugo (Shugo Maeda) almost 4 years ago

  • Status changed from Open to Rejected

Andrei Balcanasu wrote:

Good point, but this still does not explain why in some cases -7 works:

now = Date.today
=> #<Date: 2015-10-26 ((2457322j,0s,0n),+0s,2299161j)>
now -7
=> #<Date: 2015-10-19 ((2457315j,0s,0n),+0s,2299161j)>

If x is a reference to a local variable, x -y is interpreted as x - y.
Otherwise, x -y is interpreted as x(-y).

def x(y)
  :x
end

p(x -2) #=> :x
x = 1
p(x -2) #=> -1

This behavior is irrelevant to Date, so if you don't like it, please file another ticket.

Updated by nobu (Nobuyoshi Nakada) almost 4 years ago

If you were use -w option, you were warned.

$ ruby -wc -e 'Date.today -7' -e 'now = Date.today' -e 'p now -7'
-e:1: warning: ambiguous first argument; put parentheses or a space even after `-' operator
-e:3: warning: `-' after local variable or literal is interpreted as binary operator
-e:3: warning: even though it seems like unary operator
Syntax OK

Updated by andreionut (Andrei Balcanasu) almost 4 years ago

Right, that is clear now for me.
Thanks for explaining.

I don't know how to close the bug, so whomever has access, please close

Also available in: Atom PDF