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.

Ferramentas pessoais