Capítulo 08
De Guru-SP
Procs (ou blocos em variáveis)
Em Ruby temos um conceito interessante, que são os Procs, ou blocos de código associados a um objeto. Isso é possível por que em Ruby temos uma classe, Proc, que é uma classe que trata procedimentos.
Como vimos acima blocos são um recurso muito útil da linguagem, e serão exaustivamente usados daqui pra frente. Vejamos então como criar um Proc.
Ruby possibilita a criação de um Proc através de três formas distintas, como pode ser visto a seguir:
- com o uso de lambda, que instância a classe e verifica os parâmetros em tempo de execução;
- com o uso de proc, que funciona como o lambda;
- através da instanciação direta da classe usando Proc.new.
Vamos ver os três métodos abaixo e sua respectiva execução. Repare na quantidade de métodos que é passada e o retorno do interpretador:
#definindo o bloco
meu_bloco = lambda{|v1, v2, v3| v1 + v2 + v3}
#chamando com o número correto de parâmetros
puts meu_bloco.call(5,8,3)
#chamando com parâmetros a mais
puts meu_bloco.call(5,8,3,1,5)
#chamando com parâmetros a menos
puts meu_bloco.call(5,8)
E o resultado da execução:
$ ruby 10.rb 16 10.rb:3: wrong number of arguments (5 for 3) (ArgumentError) from 10.rb:9:in `call' from 10.rb:9
Repare que, com o lambda, o interpretador verificou o número de argumentos e, como tínhamos argumentos a mais, ele interrompeu a execução. Vamos agora usar o proc para definir o nosso bloco e ver o que acontece:
#definindo o bloco
meu_bloco = proc{|v1, v2, v3| v1 + v2 + v3}
#[o resto do código continua igual]
E o resultado:
$ ruby 10.rb 16 10.rb:3: wrong number of arguments (5 for 3) (ArgumentError) from 10.rb:9:in `call' from 10.rb:9
Exatamente a mesma coisa, ou seja, proc e lambda possuem praticamente o mesmo comportamento. Porém o comportamento com Proc.new é um pouco diferente:
#definindo o bloco
meu_bloco = Proc.new{|v1, v2, v3| v1 + v2 + v3}
#[o resto do código continua igual]
E o resultado da execução:
$ ruby 10.rb 16 16 10.rb:3:in `+': nil can't be coerced into Fixnum (TypeError) from 10.rb:3 from 10.rb:12:in `call' from 10.rb:12
Com Proc.new não ocorre verificação de parâmetros na passagem, tanto que o erro que acontece é quando temos menos parâmetros e o interpretador não consegue transformar um valor nulo (nil, palavra reservada do Ruby) em um Fixnum.
Quando passamos mais parâmetros o interpretador simplesmente ignora os parâmetros adicionais. Tanto que, na execução, o resultado da primeira e da segunda chamada foi o mesmo.
Voltar para o tutorial de Ruby, ou ir para o Capítulo 09.
