2

I am using this gem. When I use the following syntax, it works fine:

every :day do
  rake 'billing:daily'
end

However, when I use the following syntax, the gem is giving me syntax error:

every :day { rake 'billing:daily' }

Output:

~/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/whenever-0.10.0/lib/whenever/job_list.rb:25:in `instance_eval': config/schedule.rb:26: syntax error, unexpected '{', expecting end-of-input (SyntaxError)
every :day { rake 'billing:daily' }
            ^
    from ~/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/whenever-0.10.0/lib/whenever/job_list.rb:25:in `initialize'
    from ~/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/whenever-0.10.0/lib/whenever.rb:12:in `new'
    from ~/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/whenever-0.10.0/lib/whenever.rb:12:in `cron'
    from ~/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/whenever-0.10.0/lib/whenever/command_line.rb:42:in `run'
    from ~/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/whenever-0.10.0/lib/whenever/command_line.rb:6:in `execute'
    from ~/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/whenever-0.10.0/bin/whenever:44:in `<top (required)>'
    from ~/.rbenv/versions/2.4.3/bin/whenever:23:in `load'
    from ~/.rbenv/versions/2.4.3/bin/whenever:23:in `<main>'

Aren't both the same thing? Why is the former working but not the latter?

Utku
  • 2,025
  • 22
  • 42
  • 1
    The documentation for [block argument](http://ruby-doc.org/core-2.5.1/doc/syntax/calling_methods_rdoc.html#label-Block+Argument) explains the difference between `{ ... }` and `do ... end`. – Stefan Jun 21 '18 at 14:50
  • See also: [do..end vs curly braces for blocks in Ruby](https://stackoverflow.com/q/5587264/421705) – Holger Just Jun 21 '18 at 15:11
  • You could go with `every :day, &->{ rake 'billing:daily'}` if you really wanted to :) – engineersmnky Jun 21 '18 at 17:32

2 Answers2

8

It's a parsing/precedence issue. Braces try to bind to the nearest token, which is :day in this case, but you want it to bind to every(). You have to write every(:day) { rake 'billing:daily' } to explicitly bind it to the correct token.

mwp
  • 8,217
  • 20
  • 26
1

In ruby 2.4.2 was introduced regression in block parsing. While in ruby 2.4.1 you could use:

every :day { rake 'billing:daily' }

in ruby 2.4.2 you have to wrap the function parameters in brackets if you call it with a block otherwise you will get a SyntaxError:

every(:day) { rake 'billing:daily' }

Hirurg103
  • 4,783
  • 2
  • 34
  • 50