asfernandes
This blog has a new home: https://asfernandes.github.io

Em geral as linguagens de programação são bem parecidas e por esse motivo acho fácil aprender novas linguagens. E o que dizer então quando uma se chama Java e a outra JavaScript? :)
Ultimamente tenho programado bastante em JavaScript. Apesar de não conhecer ainda todos os detalhes da linguagem, tenho me virado bem, porém, hoje perdi um certo tempo programando em JavaScript como se estivesse programando em Java.
Simplificação do código em JavaScript:
var i = 0;
var ar = [];

while (i < 2)
{
    var n = i;
    
    ar.push(function() {
        return n;
    });

    ++i;
}

console.log(ar[0]());   // 1
console.log(ar[1]());   // 1

Neste trecho de código acima, esperava que imprimisse as linhas 0 e 1, como no código abaixo equivalente em Java, porém imprime 1 e 1.
Código em Java (8) supostamente equivalente:
int i = 0;
ArrayList<Supplier<Integer>> ar = new ArrayList<>();

while (i < 2)
{
    int n = i;

    ar.add(() -> n);
    ++i;
}

System.out.println(ar.get(0).get()); // 0
System.out.println(ar.get(1).get()); // 1
Enquanto que o código Java carrega o valor de "n" ("closure" - entre aspas porque no Java isso não é bem uma closure) para a expressão lambda com o valor de cada iteração do while, o código JavaScript carrega apenas uma variável "n", que é alterada em cada iteração. Isso acontece porque as regras de escopo de variáveis do JavaScript são totalmente diferentes de Java.
O código JavaScript abaixo que é equivalente ao código Java e retorna 0 e 1:

var i = 0;
var ar = [];

while (i < 2)
{
    (function(n) {
        ar.push(function() {
            return n;
        })
    })(i);

    ++i;
}

console.log(ar[0]()); // 0
console.log(ar[1]()); // 1

Passando "i" para o parâmetro "n" da função anônima, criamos um novo escopo.

 

Na Nota Técnica 2014/002 da Nota Fiscal Eletrônica, o governo brasileiro do PT, por falta do que fazer com o intuito de evoluir o sistema, substituiu o web service de consulta de NF-e emitidas por terceiros pelo web service de distribuição de documentos fiscais.

Definiram que a partir de 06/10/2014 o novo web service já estaria funcionando no ambiente de produção, enquanto o antigo seria desativado em 02/02/2015. Estava tentando há duas semanas usar o novo web service e ele ainda não funcionava. Hoje consegui.

O web service retornou resposta, mas é claro, resposta errada que não é validada pelo próprio schema distribuído por eles. Como uso Java com JAXB, após desativar a validação da resposta, o conteúdo do arquivo não estava sendo "desserializado" corretamente.

Eles criaram uma tag DocZip que armazena um XML compactado com GZIP no formato BASE-64 e declararam o conteúdo da tag como se tivesse um documento XML. É óbvio que algo em BASE-64 não é um XML válido.

Como o governo incompetente não testa o que faz, tive que corrigir o schema e estou disponibilizando para que outros também não percam tempo. Mesmo sem saber escrever schemas XML, cheguei nessa dúvida que me ajudou a fazer a correção.

Link para o arquivo retDistDFeInt_v1.00.xsd corrigido

Link para o diff/patch contra o arquivo XSD original

Edit:

Se tem uma coisa pior que incompetência que acontece com muita frequência na Receita Federal do PT ultimamente é a sacanagem. Após escrever esse artigo, mandei a mesma informação através do Fale Conosco, e antes mesmo de obter resposta (geralmente é um robô que responde algo sem sentido), desconfiei de uma coisa e fui verificar.

A Receita Federal, na tentativa de esconder seus erros, costuma lançar correções de arquivos e disponibilizá-los com o mesmo número de versão. E não é que aconteceu exatamente isso agora?

Tenho o arquivo PL_NFeDistDFe_100.zip com data de 07/01/2015 que tinha o problema. O arquivo presente nesta página nesse momento tem o mesmo nome e diz que foi atualizado em 19/09/2014, porém ele já está corrigido!