Developers, A saga JEDI

Dirceu Jr.

  • 04:33:34 pm on June 6, 2008 | # |

    Peter Cooper do Ruby Inside havia publicado a algum tempo um artigo com várias magicas desconhecidas da linguagem chamado 21 Ruby Tricks You Shold Be Using In Your Own Code.

    Uma que achei muito interessante é a seguinte:

    #7 - Atalho para definição de variável local
    Em vez de definir antes do uso uma variável local com algum valor inicial qualquer (como por exemplo array = []) você pode simplesmente fazer isso em tempo de execução:

    (z ||= []) << 'boo'

    Veja que na verdade você terá dois operadores na mesma linha (linguagens script são animais, não são?).

    A primeira operação que está agrupada com parênteses (z ||= []) funciona assim:

    Se o que estiver antes do “||” retornar nil então o interpretador executa a operação imediata (no caso a definição “=”). Porém caso a variável não for nil, o interpretador simplesmente pula a operação imediata e continua a evaluar a linha, no caso ele chegaria a outro operador: “<<".

    É como fazer:

    if z == nil
    z = []
    end
    z << 'boo'

    Note que caso a comparação seja feita dentro de um loop, você somente estará adicionando mais processamento ao interpretador (juro que faço benchmark mais tarde e estudo a possibilidade do interpretador ser inteligente a ponto de filtrar essa ocorrência antes de realmente executar o codigo).

    De qualquer forma é interessante notar que a lógica por traz dessa possibilidade é a mesma existente em linguagens como Lisp e Haskell. Totalmente baseada em programação funcional.

    Legal como Ruby não consegue se enquadrar em classificações como “puramente funcional” ou “puramente imperativas” e na verdade faz um mix disso :)

    Update:
    O bench só me mostrou algo obvio: A utilização de um operador a mais dentro do loop custa processamento. Como para chegar a tempos de execução medidos em segundos meu loop foi de 10 milhões de iterações, creio que no dia-a-dia a utilização de uma ou outra tecnica possa ficar ao gosto do programador.

    Aqui estão os arquivos utilizados para o teste: bench.rb e bench2.rb (com ||=).

    Na maquina que utilizei para os testes:
    iMac-Dirs:Desktop dirs$ ruby bench.rb;ruby bench2.rb
    3.3111
    6.259219

    Update 2:
    Para exemplificar de forma mais lógica o operador ||=, ele é na realidade mais parecido com essa forma comum em linguagens script:

    (z || z = []) << 'boo'

    Do que com o código que passei anteriormente.

     

Leave a Comment