The following example is working even if the block signature in the second call is different from the definition. Is this expected behaviour or a bug?
def hello(&block : String, String -> String)
puts "---"
puts typeof(block)
puts "Before Block"
puts block.call("1", "2")
puts "After Block"
end
hello do |first, second|
"#{first} #{second}"
end
hello do |first|
"#{first} only"
end
Output:
---
Proc(String, String, String)
Before Block
1 2
After Block
---
Proc(String, String, String)
Before Block
1 only
After Block
$ crystal --version
Crystal 1.3.2 [932f193ae] (2022-01-18)
LLVM: 10.0.0
Default target: x86_64-unknown-linux-gnu
This is expected behavior. The caller can omit block arguments but not add extra ones. The reason is that we want to allow things like this:
3.times do
puts "Hello!"
end
10.times do |i|
puts "#{i}**2 = #{i**2}"
end
That is, an argument is always given to the block, but the caller might choose to omit it.
A follow up question is: what API are you trying to achieve?
1 Like
That makes sense. Thanks.
A follow up question is: what API are you trying to achieve?
API is not broken, it was just confusion. Now it is clear.
This is used in the Storage Manager project for Kadalu Storage/GlusterFS. Today I accidentally discovered that all tests passed even without all the block arguments (GH issue).
Example helper to create CLI subcommand: mgr/src/cmds/helpers.cr
and its usage: mgr/src/cmds/volumes.cr
1 Like
Incredible and very well done project (Kadalu).
1 Like