Posts de Janeiro, 2008

h1

Empresa familiar

2008/01/28

Quando comentei que ouvi o camelô no ônibus dizer de que seu produto era enriquecido com ‘carbono-hidratos’ e outro dizer que o seu tinha ‘90% de calorias’, ouvi uma estória ainda mais interessante. Meu amigo presenciou no trem um camelô com o seguinte bordão: “Compre a bala da empresa familiar. Meu pai planta, minha irmã colhe, minha mãe beneficia e eu vendo no trem”. A bala era igual a todas as outras.

h1

Split em Lua

2008/01/27

É normal que um programador, ao se deparar com uma nova linguagem, tente recriar recursos úteis de linguagens já conhecidas. Não raro, fazemos isso por ignorância dos recursos disponíveis. No meu caso, senti falta do método String.split() de Java ao codificar um algoritmo em Lua.

Inicialmente escrevi o algoritmo usando o método string:gmatch() da API de Lua, porém, o resultado é ligeiramente diferente. Suponha que temos uma string como o início de uma carta “Caro Fulano,\n\nBlah, blah, blah…” e queremos separar o texto linha por linha. Em Java, usaríamos texto.split(“\n”) e o resultado no texto acima, daria 3 linhas. Entretanto, se usássemos texto:gmatch(“[^\n]+”), a função não capturaria a linha vazia, retornando apenas duas. Além disso, temos o inconveniente de ter que inverter a expressão regular.

Sendo assim, resolvi criar meu próprio método string:split(). Ei-lo:

function string:split(separator)
    local init = 1
    return function()
        if init == nil then return nil end
        local i, j = self:find(separator, init)
        local result
        if i ~= nil then
            result = self:sub(init, i – 1)
            init = j + 1
        else
            result = self:sub(init)
            init = nil
        end
        return result
    end
end

Assim como o método string:gmatch(), em vez de retorna um array, este retorna um iterador que pode ser usando em um for. Além disso, a partir dessa definição, já podemos invocar “texto tal”:split(“regex”), como se fosse nativo da biblioteca de strings. No exemplo no início desse post, poderíamos fazer for linha in texto:split(“\n”) do print(linha) end para imprimir o texto linha por linha.

Observe que esse código cria e retorna uma função que usa uma variável da que a criou. Isso se chama closure e é muito útil. Algo como inner classes em Java, porém bem mais flexível e sucinto. A palavra self é equivalente ao this de Java e nesse caso é a própria string.

Lua é uma linguagem realmente muito interessante. Merece toda fama que possui. Experimentem! O irônico é que precisei sair do Tecgraf para me interessar por ela. Isso tem a ver um traço recorrente da minha personalidade, mas isso é assunto para outro post.