Uma Proc representa o ponteiro de uma função com um contexto opcional (os dados do ambiente). Geralmente é criado com um literal de proc:
# Uma proc sem argumentos:
->{ 1 } # Proc(Int32)
# Uma proc com um argumento:
->(x : Int32) { x.to_s } # Proc(Int32, String)
# Uma proc com dois argumentos:
->(x : Int32, y : Int32) { x + y } # Proc(Int32, Int32, Int32)
Os tipos dos argumentos são obrigatórios, exceto ao enviar diretamente um literal de proc a uma fun
de uma lib em bindings para C.
O tipo do retorno é inferido do corpo da proc.
Também é disponibilizado um método new
especial:
Proc(Int32, String).new { |x| x.to_s } # Proc(Int32, String)
Esta forma permite que você especifique o tipo de retorno e verifique-o em relação ao corpo da proc.
Para denotar o tipo Proc, você pode escrever:
# Uma Proc aceitando um único argumento Int32 e retornando uma String
Proc(Int32, String)
# Uma proc que não aceita nenhum argumento e retorna Void
Proc(Void)
# Uma proc que aceita dois argumentos (um Int32 e uma String) e retorna um Char
Proc(Int32, String, Char)
Nas restrições de tipos, argumentos de tipo genérico e outros lugares onde espera-se um tipo, você pode usar uma sintaxe mais curta, conforme explicado no capítulo sobre tipos:
# Um array de Proc(Int32, String, Char)
Array(Int32, String -> Char)
Para invocar uma Proc, você chama o método call
dela. O número de argumentos deve coincidir com o tipo da proc:
proc = ->(x : Int32, y : Int32) { x + y }
proc.call(1, 2) #=> 3
Uma Proc pode ser criada a partir de um método existente:
def one
1
end
proc = ->one
proc.call #=> 1
Se o método tiver argumentos, você precisa especificar seus tipos:
def plus_one(x)
x + 1
end
proc = ->plus_one(Int32)
proc.call(41) #=> 42
Uma proc pode opcionalmente especificar um receptáculo:
str = "hello"
proc = ->str.count(Char)
proc.call('e') #=> 1
proc.call('l') #=> 2