Mudando a página inicial padrão no Grails

30.Janeiro.2009
Ao se criar uma aplicação padrão em Grails, a página inicial é o index.gsp, que fica na pasta web-app.

Por algum motivo que não interessa para o momento, a minha aplicação estava ficando torta com essa configuração. Comecei a misturar página estática com gambiarra para suprir a ausência de um controller.

Como a gambiarra é um bumerangue, e para não fugir do MVC, é possível resolver isso alterando o arquivo grails-app/conf/UrlMappings.groovy, da forma abaixo:

class UrlMappings {
  static mappings = {
    "/$controller/$action?/$id?"{
      constraints {
        // apply constraints here
      }
    }
    "500"(view:'/error')
    "/" {
      controller = "app"
      action = "login"
    }
  }
}

O controller app, que é onde eu centralizo o fluxo da aplicação, fica da seguinte maneira:

class AppController {
  def login = {
    render (view: 'login')
  }
}

Aí você pergunta: ‘mas para que tanta complicação se a action apenas renderiza uma view?’

De fato, é apenas esforço inútil. Porém, se eu quiser que o usuário, devidamente autenticado, seja redirecionado para a tela principal da aplicação sem ter que passar novamente pelo login, posso alterar o código para que a action resolva isso:

  def login = {
    if(session.user)
      render (view: 'telaInicial')
    else
      render (view: 'login')
  }

Fica ao gosto do freguês, claro.


On the road

28.Janeiro.2009
Acho que a parte mais difícil de se viajar a trabalho, profissionalmente falando, é o choque cultural com os nativos do lugar.

O ritmo invariavelmente vai ser outro, a velocidade de execução, e muitas vezes até mesmo o comprometimento vai ser motivo para perder a calma.

Não se pode mudar o mundo, afinal. Quem me garante que são eles os errados?


Aprenda a falar

27.Janeiro.2009
Não é randômico, seu imbecil. É aleatório.

ASCII não se pronuncia ASK-DOIS, sua mula, mas sim ASKI.

Você não imputa dados, sua besta. Você insere, digita, informa. Imputar é atribuir culpa ou delito a algo ou alguém.

Sua máquina não tem dois gigas, mas sim dois giga, ou dois gigabytes, criatura.

Aprenda a falar, bicho burro. Pelo bem dos meus ouvidos, que não são penico.


Comunicação é tudo e mais um pouco

26.Janeiro.2009
Imagine que você receba a seguinte especificação:

Pegue uma folha de papel A4. Sob a mesa, dobre-a ao meio. Coloque a folha dobrada sobre a mesa.

A especificação parece clara e simples, mas aposto que dobramos as folhas de forma diferente, obtendo resultados diferentes. Eu dobrei a minha folha verticalmente, enquanto provavelmente você dobrou horizontalmente, obtendo uma forma próxima de um quadrado.

Qual foi o problema?

Eu criei uma especificação tendo em mente exatamente o que eu queria. E eu acreditei que aquilo era mais do que suficiente.

Você pegou uma especificação, aparentemente muito simples, e sem questionar seguiu os passos que julgou corretos.

Não houve comunicação, cada parte presumiu coisas e o resultado final não foi o esperado.

O grande diferencial das ditas metodologia ágeis é exatamente permitir a comunicação rápida, clara e sem ruídos entre todos os membros da equipe. Isso não tem nada a ver com post-its, gráficos ou ferramentas na Internet. É por isso que estamos vendo-as falhar, e é por isso que o seu projeto, e o meu, também estão falhando.

É por isso que relacionamentos chegam a níveis insuportáveis de convivência, casamentos terminam, empregos viram um inferno. É por isso que ocorrem desencontros, é por isso que clientes recebem algo que não pediram e que não os atendem.

É por isso também que não consegui comprar um mísero pão doce quando estive fora do país.

Comunicação é, na minha opinião, o fator mais importante, e o menos valorizado. É tudo isso que eu falei, e mais um pouco.


Falar é fácil…

23.Janeiro.2009
Num mundo perfeito, a vida profissional serve para dar condições de termos uma vida pessoal decente e, por que não, divertida.

A menos que você seja chamado para trabalhar nas ilhas Cook, não é o que acaba acontecendo.

Bom fim de semana.


The Shark Jumper

22.Janeiro.2009

“Zed Shaw (…) is the author the Mongrel web server, creator of the Utu project, recent Factor convert, and absolutely hates Ruby even though he makes money on it.”

Sujeito ganhou ponto comigo depois dessa.


Obama

20.Janeiro.2009
ObamisEstava pensando aqui, enquanto a aplicação compila e me veio uma associação meio torta: seria Obama o novo Ruby na presidência americana?

O Ruby foi (e por alguns ainda é) tido como a grande salvação do desenvolvimento de software. É fácil de utilizar, fácil de entender e faz com que você pareça cool, ao contrário do paquidérmico, verboso e velho Java.

Por outro lado, é uma linguagem que eu não consigo levar a sério. Tanto pelo hype, quanto pela imaturidade. Trouxe excelentes “novas” idéias, ótimas soluções para problemas que a maioria das pessoas fazia de conta que não estavam lá, mas corporativamente continua com o status de ‘brinquedo’.

Honestamente, espero que ele (o Obama) faça um excelente trabalho, deixe muita coisa boa para as futuras gerações, mas não acho que ele seja o novo Messias, como está sendo propagandeado por aí.

Nem ele, nem qualquer outra linguagem da moda.


Hail for Grails

19.Janeiro.2009
Infelizmente não estou tendo o tempo que gostaria para investir no Clojure. Porém, por uma coincidência, surgiu uma oportunidade para trabalhar com Grails (Groovy on Rails), uma versão Groovy do consagrado framework para Ruby.

Minha primeira impressão foi muito boa. Para montar um CRUD, são necessários menos de cinco minutos, caso você nunca tenha mexido antes com o framework.

“Ah, mas o Rails também tem isso”. Claro que tem, afinal de contas, o Grails é um ‘clone’ que roda com Groovy. É possível gerar um arquivo .war e publicar a aplicação num servidor Tomcat, como uma aplicação Java normal. Por trás dos panos, o que acontece é exatamente compilar o código Groovy para Java, e o Java para o bytecode da JVM. Caso você tenha uma aplicação Rails, pode também utilizar o JRuby para o mesmo fim.

Outro ponto que me chamou a atenção no Grails (ou no Groovy, se preferir) são as contraints. São checagens que você codifica na própria entidade, que funcionam como validações automáticas dos dados inseridos. Numa tela de login, por exemplo, você pode ter uma entidade User e informar que login é único, não pode estar em branco e deve ter entre 5 e 20 caracteres, por exemplo. Tudo isso em uma ou duas linhas de código facilmente legível.

Como o trabalho deve ser entregue rapidamente, não vou ter muito tempo de fuçar e experimentar funcionalidades não usuais, mas com certeza o framework já entra para a minha lista de ferramentas preferidas.

Aos mais puristas, deixo meu compromisso de estudar Ruby e olhar o Rails com mais atenção, já que, ao que me parece, esses frameworks atendem plenamente às minhas necessidades.


Tipo byte em Java

15.Janeiro.2009
O tipo byte, na linguagem Java, tem comprimento de oito bits e armazena valores inteiros entre -127 e 128.

No post anterior eu citei o caso do método que recebia 255 e retornava -1. Isso acontece por que qualquer valor acima de 128 e menor que 256 (o máximo passa a ser representado usando oito bits) passa a ser representado como um valor negativo.

Exemplo:

byte exemplo1 = 127; // por ser menor que 128, não precisa de cast
byte exemplo2 = (byte) 255; // por ser maior que 128, o cast é necessário
byte exemplo3 = (byte) 254; // idem acima

println(exemplo1); // mostra 127
println(exemplo2); // mostra -1
println(exemplo3); // mostra -2

Qualquer valor menor que -127 e maior que 128 exise um cast (ou typecast, ou ‘coerção de dados’) para ser atribuído.

Cast é quando você força um valor de um tipo a ser de outro tipo. No caso ilustrado acima, valores menores que -127 e maiores que 128 são considerados como sendo do tipo int, exigindo a conversão antes da atribuição.


O caso do byte perdido

14.Janeiro.2009
Encontre o erro:

public class AnyInputStream extends InputStream {
  private byte getTheNextByteFromSomewhereElse(){
    // do something useful
  }

  public int read() {
    byte result = -1;
    if(!(hasAnyKindOfError() || wasTheLastByte())) {
      result = getTheNextByteFromSomewhereElse();
    }
    return result;
  }
}

A propósito, os nomes estranhos de métodos e da classe são meramente ilustrativos, para auxiliar na compreensão.

Qual o problema do fonte?

Quando você tem algum erro de leitura, ou chega ao final do conteúdo, recebe um -1 como resposta. Caso contrário, recebe o próximo byte e assim por diante. O problema ocorre quando você lê um byte de valor 255.

Se você jogar o valor 255 numa variável de typo byte, no Java, ele passa a ser -1, por questões de overflow e tamanho de variável. Ou seja: um byte válido passa a ser compreendido como final de arquivo ou erro de leitura.

Um simples teste teria pego esse erro ainda na mesa do programador e ele não teria chegado ao ambiente de produção.

Então eu pergunto:
- qual o problema em testar a droga da funcionalidade antes de entregar?
- qual o problema em gastar alguns segundos pensando antes de escrever?
- qual o problema em prestar atenção na merda que você, supondo que seja um desenvolvedor, está fazendo?

São essas coisas que me fazem achar que estou me preocupando em limpar os pés para entrar numa sala cheia de lama.