Proc

A Proc represents a function pointer with an optional context (the closure data). It is typically created with a proc literal:

  1. # A proc without arguments
  2. ->{ 1 } # Proc(Int32)
  3. # A proc with one argument
  4. ->(x : Int32) { x.to_s } # Proc(Int32, String)
  5. # A proc with two arguments:
  6. ->(x : Int32, y : Int32) { x + y } # Proc(Int32, Int32, Int32)

The types of the arguments are mandatory, except when directly sending a proc literal to a lib fun in C bindings.

The return type is inferred from the proc’s body.

A special new method is provided too:

  1. Proc(Int32, String).new { |x| x.to_s } # Proc(Int32, String)

This form allows you to specify the return type and to check it against the proc’s body.

The Proc type

To denote a Proc type you can write:

  1. # A Proc accepting a single Int32 argument and returning a String
  2. Proc(Int32, String)
  3. # A proc accepting no arguments and returning Void
  4. Proc(Void)
  5. # A proc accepting two arguments (one Int32 and one String) and returning a Char
  6. Proc(Int32, String, Char)

In type restrictions, generic type arguments and other places where a type is expected, you can use a shorter syntax, as explained in the type:

  1. # An array of Proc(Int32, String, Char)
  2. Array(Int32, String -> Char)

Invoking

To invoke a Proc, you invoke the call method on it. The number of arguments must match the proc’s type:

  1. proc = ->(x : Int32, y : Int32) { x + y }
  2. proc.call(1, 2) #=> 3

From methods

A Proc can be created from an existing method:

  1. def one
  2. 1
  3. end
  4. proc = ->one
  5. proc.call #=> 1

If the method has arguments, you must specify their types:

  1. def plus_one(x)
  2. x + 1
  3. end
  4. proc = ->plus_one(Int32)
  5. proc.call(41) #=> 42

A proc can optionally specify a receiver:

  1. str = "hello"
  2. proc = ->str.count(Char)
  3. proc.call('e') #=> 1
  4. proc.call('l') #=> 2