Crystal: Block argument isn't seen inside macro code

Created on 13 Jul 2016  路  5Comments  路  Source: crystal-lang/crystal

      def sidekiq_options(&block : Sidekiq::Job -> Void)
        {% begin %}
        Sidekiq::Worker::OPTION_BLOCKS["{{@type.id}}"] = block
        {% end %}
      end
Error in ./examples/sidekiq.cr:11: instantiating 'sidekiq_options()'

  sidekiq_options do |job|
  ^~~~~~~~~~~~~~~

in macro 'macro_4614465168' /Users/mike/src/sidekiq.cr/src/sidekiq/worker.cr:132, line 2:

  1. 
  2.         Sidekiq::Worker::OPTION_BLOCKS["CrystalWorker"] = block
  3.         

        Sidekiq::Worker::OPTION_BLOCKS["CrystalWorker"] = block
                                                          ^~~~~

undefined local variable or method 'block'

What am I doing wrong?

bug compiler

Most helpful comment

This is still broken. Minimal code to reproduce:

def callback(&block)
  {% begin %}
    block
  {% end %}
end

block = callback { puts 1 }
block.call

@vlazar By the way, thank you for looking at old issues! 馃檹

All 5 comments

Hmmm... it's kind of a bug, but I'm not sure.

The thing is, the compiler knows a block needs to be converted to a Proc when you use it. This is done at the parser level. But if the block is mentioned inside a macro it doesn't see this, because macro is just text with interpolation, no meaning inside it until it's parsed.

A workaround is to assign block to another variable, and then use it inside the macro:

def sidekiq_options(&block : Sidekiq::Job -> Void)
  captured_block = block
  {% begin %}
  Sidekiq::Worker::OPTION_BLOCKS["{{@type.id}}"] = captured_block
  {% end %}
end

Until we think of a way to solve this, I'd use the workaround.

Thanks, that works perfectly!

codetriage

This came up today, and we still get a similar message of:

undefined local variable or method 'block'

from this kind of example - so it hasn't been handled yet.

Is this something worth continuing to consider, or should the macro docs be updated to account for this behavior?

Tried it in Crystal 0.31.1 on MacOS with sidekiq.cr from master branch and it works for me.

(I assume the error was happening when running https://github.com/mperham/sidekiq.cr/blob/25b1abcb4791d2b33d76286cd5ee049fcf45bbfd/examples/sidekiq.crr.)

$ crystal --version
Crystal 0.31.1 (2019-10-02)

LLVM: 8.0.1
Default target: x86_64-apple-macosx


Output

$ crystal lib/sidekiq/examples/sidekiq.cr
2019-10-13T13:22:57.466Z 21667 TID-1zj91kg  INFO: Pushing job 8e75d30b7499ce190963c5a9
2019-10-13T13:22:57.468Z 21667 TID-1zj91kg  INFO: Pushing job 3474e2fb67aeee3189919253


         m,
         `$b
    .ss,  $$:         .,d$
    `$$P,d$P'    .,md$P"'
     ,$$$$$bmmd$$$P^'
   .d$$$$$$$$$$P'
   $$^' `"^$$$'       ____  _     _      _    _
   $:     ,$$:       / ___|(_) __| | ___| | _(_) __ _
   `b     :$$        \___ \| |/ _` |/ _ \ |/ / |/ _` |
          $$:         ___) | | (_| |  __/   <| | (_| |
          $$         |____/|_|\__,_|\___|_|\_\_|\__, |
        .d$$                                       |_|

2019-10-13T13:22:57.469Z 21667 TID-1zj91kg  INFO: Sidekiq v0.6.1 in Crystal 0.31.1
2019-10-13T13:22:57.469Z 21667 TID-1zj91kg  INFO: Licensed for use under the terms of the GNU LGPL-3.0 license.
2019-10-13T13:22:57.469Z 21667 TID-1zj91kg  INFO: Upgrade to Sidekiq Enterprise for more features and support: http://sidekiq.org
2019-10-13T13:22:57.469Z 21667 TID-1zj91kg  INFO: Starting processing with 25 workers
2019-10-13T13:22:57.469Z 21667 TID-1zj91kg  INFO: Press Ctrl-C to stop
2019-10-13T13:22:57.472Z 21667 TID-1zj90gg  JID=8e75d30b7499ce190963c5a9 INFO: Start
2019-10-13T13:22:57.472Z 21667 TID-1zj90gg  JID=8e75d30b7499ce190963c5a9 INFO: Executing job 8e75d30b7499ce190963c5a9
2019-10-13T13:22:57.472Z 21667 TID-1zj90gg  JID=8e75d30b7499ce190963c5a9 INFO: hello!
2019-10-13T13:22:57.473Z 21667 TID-1zj90gg  JID=8e75d30b7499ce190963c5a9 INFO: Done: 0.000301 sec
2019-10-13T13:22:57.474Z 21667 TID-1zj90gg  JID=3474e2fb67aeee3189919253 INFO: Start
2019-10-13T13:22:57.475Z 21667 TID-1zj90gg  JID=3474e2fb67aeee3189919253 INFO: Executing job 3474e2fb67aeee3189919253
2019-10-13T13:22:57.475Z 21667 TID-1zj90gg  JID=3474e2fb67aeee3189919253 INFO: hello!
2019-10-13T13:22:57.475Z 21667 TID-1zj90gg  JID=3474e2fb67aeee3189919253 INFO: Done: 0.000244 sec

This is still broken. Minimal code to reproduce:

def callback(&block)
  {% begin %}
    block
  {% end %}
end

block = callback { puts 1 }
block.call

@vlazar By the way, thank you for looking at old issues! 馃檹

Was this page helpful?
0 / 5 - 0 ratings

Related issues

grosser picture grosser  路  3Comments

relonger picture relonger  路  3Comments

cjgajard picture cjgajard  路  3Comments

asterite picture asterite  路  3Comments

asterite picture asterite  路  3Comments