Crystal: block.call not work

Created on 24 Aug 2018  路  4Comments  路  Source: crystal-lang/crystal

I try to use code from this issue

def call(&block)
  block.call(3, "test")
end

call do |x, y|
  puts x
  {x, y}
end

But only get error:

wrong number of block arguments (given 2, expected 0)

Is it ok, maybe there is some other way to call block?

Playground link: https://play.crystal-lang.org/#/r/4t8h

Most helpful comment

Maybe an untyped block argument shouldn't have a default type but rather be a syntax error if it is used as a proc. This would more clearly describe the error than failing because of mismatched arguments.
It would also be consistent with regular arguments as when there is no type restriction, it is simply untyped instead of having a default type.
An untyped &block argument could still be used with yield. Although it is not strictly necessary to specify the argument, it makes it more clear that the method expects a block.

All 4 comments

With yield it works

def call(&block)
   yield 3, "test"
end

call do |x, y|
  puts x
  {x, y}
end

@j8r Yes, but I want do something like this

def capture(&block)
  block
end

def invoke(&block)
  block.call(12)
end

proc = capture {|param| puts param }
invoke(&proc)

And it's produce error too

In order to use block.call the block argument needs to be captured as a Proc. A captured block needs to be typed and since you didn't specify any type restrictions for the block argument, it is by default Proc(Nil). You need to specify the proc arguments as &block : Proc(Int32, String, Nil) (for example). Equivalent is &block : Int32, String ->.

def call(&block : Int32, String -> )
  block.call(3, "test")
end

call do |x, y|
  puts x
  {x, y}
end

See Capturing blocks in the language reference.

Maybe an untyped block argument shouldn't have a default type but rather be a syntax error if it is used as a proc. This would more clearly describe the error than failing because of mismatched arguments.
It would also be consistent with regular arguments as when there is no type restriction, it is simply untyped instead of having a default type.
An untyped &block argument could still be used with yield. Although it is not strictly necessary to specify the argument, it makes it more clear that the method expects a block.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lgphp picture lgphp  路  3Comments

pbrusco picture pbrusco  路  3Comments

oprypin picture oprypin  路  3Comments

nabeelomer picture nabeelomer  路  3Comments

jhass picture jhass  路  3Comments