6

I want to pass arguments to a Proc like using splat, but it returns an error wrong number of block arguments (1 for 0)

$callbacks = {} of String => Array(->)

def add_callback(event, &block)
  begin
    $callbacks[event.to_s] << block
  rescue
    $callbacks[event.to_s] = [block]
  end
end

add_callback(:event) do |arg|
  puts "event!"
end

$callbacks["event"].first.call

Error in line 11: wrong number of block arguments (1 for 0) http://carc.in/#/r/7gw

Hugo Abonizio
  • 84
  • 1
  • 2

1 Answers1

7

You need to specify the argument list everywhere.

class EventManager
  def initialize
    @callbacks = Hash(String, Array(String ->)).new {|h, k| h[k] = [] of String -> }
  end

  def add(event, &callback : String ->)
    @callbacks[event] << callback
  end

  def fire(event, argument : String)
    @callbacks[event].each &.call(argument)
  end
end

callbacks = EventManager.new
callbacks.add("foo") do |argument|
  puts "Got #{argument}"
end
callbacks.add("bar") do
  puts "I was called"
end
callbacks.fire "foo", "Ping"
callbacks.fire "bar", "Pong"
Jonne Haß
  • 4,792
  • 18
  • 30
  • Not fully, no. Crystal needs to know the argument list and supporting many different ones in the same collection will become fairly ugly to manage pretty soon. As I've shown it's however possible to omit block arguments you don't need. – Jonne Haß Jul 18 '15 at 21:24
  • I understand... and then I tried to make this with Hash and I think I don't understand how it works yet http://carc.in/#/r/7hk – Hugo Abonizio Jul 18 '15 at 22:26
  • 2
    If you hash doesn't interfere to the right type, you need to be a bit more explicit http://carc.in/#/r/7hm – Jonne Haß Jul 18 '15 at 22:31