Rafael Souza

Just a guy who loves to code

Meu Ambiente De Desenvolvimento Em 7 Itens

O @sa_vini me convidou para participar do último meme do momento que é descrever o ambiente onde nós, todos os dias, desenvolvemos essa coisa maravilhosa chamada software. Então lá vai.

OS

Atualmente sou um feliz usuário do Mac OS X, pra mim, ainda não existe nada igual. Depois de usar Windows por muito tempo e tentar duas distros Linux (ArchLinux e Ubuntu), comprei um Macbook e me tornei uma pessoa mais feliz.

Ruby

Eu gosto de fuçar em bastante coisa que eu vejo por ai, e Ruby sem dúvida, foi a melhor coisa que eu já fucei até hoje. Uma linguagem com sintaxe simples, porém bem poderosa e altamente extensível. Hoje Ruby é a linguagem que uso pra tudo (apesar de eu estar numa baita pilha para usar Javascript com node.js).

Git

Não sou um super-usuário de Git, mas me viro bem com ele, já usei Visual Source Safe e Subversion, porém o Git é imbatível, prático para as coisas simples e poderoso para todo o resto. Se ainda não usou, use.

Editor

Depois de uma ou duas semanas, tentando pela quinta/sexta vez, usar VIM, voltei para o TextMate, acho legal a idéia de poder fazer tudo pelo editor, mas eu só quero programar, mais nada. :)

Chrome

Na minha humilde opnião, o melhor browser já feito até hoje.

Música

Meu iTunes fica ligado direto. Pra falar bem a verdade eu não sei se música influencia na minha produtividade, já que desde sempre trabalho ouvindo música. Acho que ouço mais por hábito mesmo. Aliás, exatamente agora tá rolando um remix de Train - Hey, Soul Sister, bem bacana.

Local

Hoje trabalho no aconchego do meu lar com três cadelinhas me fazendo companhia, porém esse lar é quente like a hell e o ventiladorzinho que eu tenho aqui - praticamente em cima de mim - não dá conta do recado. Espero me mudar em breve. :)

É isso ai, meu ambiente não é lá grande coisa, nem é muito diferente dos outros, mas para as minhas tarefas diárias ele é mais do que suficiente.

Convido para participar também, @juliogreff e @joaomilho

Adicionando a Sua Chave Pública Ao Authorized_keys

Essa é uma daquelas que é fácil mas o cara nunca lembra como fazer, já precisei disso algumas vezes e sempre tinha que recorrer ao seu Google para descobrir.

ssh_copy.sh
1
ssh user@host 'mkdir ~/.ssh; echo '`cat ~/.ssh/id_rsa.pub`' >> ~/.ssh/authorized_keys'

Retirado daqui: http://snippets.dzone.com/posts/show/2335

UPDATE: O kbmurata comentou no twitter que algum server/client de ssh pode reclamar das permissões da pasta .ssh, se isso acontecer, rode:

chmod.sh
1
chmod 700 ~/.ssh

Tradutor Simples Inglês/Português E Português/Inglês

Sempre usei os bots do Google para o gtalk, mas percebi que os resultados que eles retornam são bem diferentes da página de tradução.

Então fiz uma página bem simples que usa a Language API do Google para traduzir textos do Inglês para o Português e do Português para o Inglês, sem todas aquelas opções de linguas que a página deles oferece.

Para você que tem interesse em saber como funciona traduzir textos com a Language API do Google, veja como é fácil:

jsapi.html
1
<script type="text/javascript" src="http://www.google.com/jsapi"></script>

e depois

google_load.js
1
2
3
4
5
google.load("language", "1");
google.language.translate("texto que eu quero traduzir", "pt", "en", function(result) {
// aqui voce faz o que quiser com o resultado
});

Shoes-translator Atualizado: Ruby, Shoes E Google Translate API

Há tempos atrás desenvolvi uma pequena aplicação usando Shoes, e ontem resolvi atualizá-la, mudei um pouco a aparência e melhorei o suporte a pronúncia.

shoes-translator

Caso tenha interesse em usar, você pode baixar o projeto do github: http://github.com/rafaelss/shoes-translator

Falando um pouco agora sobre o Shoes, me parece que após o sumiço do _why a coisas não vão tão bem, o projeto amadureceu muito pouco, muita coisa básica ainda é complicado de se fazer, impedindo um pouco que aplicações mais profissionais sejam feitas rodando sobre o framework.

Quando desenvolvi o shoes-translator na primeira vez, eu levava mais fé no projeto, acreditava que seria um concorrente de peso para os toolkits atuais, mas agora, voltando a mexer na código e buscando referências na internet para fazer as alterações, percebi que o Shoes ainda precisa de muito, mas muito trabalho para poder ter crédito suficiente e ser usado para fazer software de verdade.

UPDATE: O @kbmurata postou no twitter que o objetivo do Shoes é ser usado para o aprendizado de forma divertida, de qualquer forma, se você quiser começar um projeto usando Shoes, pense bem que tipo de projeto você está desenvolvendo, não pense em nada muito maior que um ”tradutor de sapatos

Compilando O Passenger Sem Espaço No /tmp

De ontem pra hoje perdi um bom tempo tentando compilar um passenger mais novo em um servidor que tem um /tmp de apenas 1MB (eu ainda preciso descobrir porque isso).

A solução é simples até, basta setar a var TMPDIR com o path de um outro diretório qualquer, mais ou menos assim:

install_passenger.sh
1
sudo TMPDIR=/home/rafaelss/tmp passenger-install-apache2-module

Detalhe: eu estava acostumado a setar variáveis ao executar um comando colocando ela na frente do comando, mas com o sudo isso não funciona. No help do sudo diz que deve ficar ali no meio

sudo.sh
1
usage: sudo [-bEHPS] [-p prompt] [-u username|#uid] [VAR=value] {-i | -s | }

Hora Extra Em Porto Alegre

O Tailor lançou a idéia no twitter e eu apoiei, então, semana que vem, #horaextra na Cidade Baixa, em Porto Alegre, mais exatamente no Copão

A idéia é juntar um monte (ou não) de nerds pra falar de trabalho, tecnologia, frameworks, programação, enfim, tudo o que a gente mais gosta

Então, segunda-feira, 19:30, Copão. Aparece lá!

ASP.NET MVC E Suas ActionResult

O framework MVC da Microsoft usa um determinado objeto para definir qual tipo de resultado/output a action executada deve retornar. São eles:

  • ContentResult - Pode ser usado para retornar textos simples.
  • EmptyResult - Esse serve para retornar resultados em branco, quando quiser que o output seja vazio.
  • HttpUnauthorizedResult - Usado quando o usuário não tem permissão para executar a action. Retorna o 401 como status da requisição.
  • JsonResult - Serializa um objeto em formato JSON, bom para ser usando em requisições AJAX.
  • RedirectResult - Resultado usado para redirecionamentos.
  • RedirectToRouteResult - Também usado para redirecionamentos, mas a URL está ligada a uma rota.
  • ViewResultBase - Classe abstrata, usada para renderizar HTMLs.
    • PartialViewResult - Estende ViewResultBase para renderizar as views e seus HTMLs.
  • BinaryResult - Classe abstrata usada para resultados binários.
    • BinaryStreamResult - Estende BinaryResult, pode ser usado para escrever imagens direto no stream do resutado.

Porém, em alguns casos, retornar um texto simples, ou um JSON pequeninho, é meio chato. Considere o código abaixo:

json_result.csharp
1
2
3
4
JsonResult json = new JsonResult();
json.ContentType = "text/javascript";
json.Data = new { success = true };
return json;

Isso poderia ser mais simples não? Porém, a classe JsonResult, e nenhuma outra ActionResult aceita parâmetros no construtor. Por isso criei duas classes que podem ser usadas como ActionResult, para simplificar essa tarefa. Elas devem ser usadas assim:

test_json.csharp
1
2
3
4
return new SimpleResult("Hello World");
return new SimpleResult(1);
return new SimpleResult(1257.14);
return new SimpleResult(true);

e

simple_json.csharp
1
return new SimpleJsonResult(new { success = true });

Pronto, agora é hora de refatorar código. :)

UPDATE: Conforme o Guilherme comentou ali embaixo, o ASP.NET MVC tem um método que já simplifica as coisas.

json_1.csharp
1
2
3
4
return Json("Hello World");
return Json(1);
return Json(1257.14);
return Json(true);

e

json_2.csharp
1
return Json(new { success = true });

jQuery, Safari E CSS Selectors

Hoje estava verificando um bug em um projeto, que acontecia somente no Safari, tanto no MacOS, quanto no Windows, e descobri que o problema era a forma como eu estava definindo o elemento HTML envolvido na história.

O expressão que eu estava usando era a seguinte:

jquery.js
1
$("#meuform input[type='hidden'][value='']").length

No Safari sempre me retornava 0, já no Firefox e Internet Explorer, retorna 1, que era para ser o valor certo no caso. Analisando como o input estava definido eu descobri o problema, ele estava definido assim:

input.html
1
<input type="hidden" name="first_user" />

Resumindo:

O Safari não acha elementos onde o atributo filtrado não esteja presente no HTML. (Estou usando a versão 1.3.2 do jQuery e 4.0 (503.17) do Safari, no Windows, mas reportaram o problema no Mac também)

C# E Códigos Deprecated

Você desenvolve uma biblioteca de utilitários para facilitar a vida dos outros desenvolvedores da empresa, porém algumas vezes é necessário refatorar códigos, criando/renomeando/apagando alguns métodos. Obviamente você não pode sair mudando tudo, existe código “antigo” usando a sua “lib”.

Existe um atributo no C# que permite que você marque código como deprecated, é o Obsolete, muito útil e fácil de usar.

obsolete_1.csharp
1
2
3
4
[Obsolete("Use o mĂŠtodo MinhaClasse.MeuMetodo(int parametro)")]
public static void MeuMetodo(string parametro) {
// ...
}

No exemplo acima quero que os desenvolvedores usem a versão que recebe um integer como parâmetro, e não mais a versão com string.

Você ainda pode dizer que é para o compilador gerar um erro ao compilar o código, passando true como segundo parâmetro do atributo.

obsolete_2.csharp
1
2
3
4
[Obsolete("Este mĂŠtodo nĂŁo deve mais ser usado. Usar MinhaClasse.MeuMetodo(int parametro)", true)]
public static void MeuMetodo(string parametro) {
// ...
}

Permissão Para O Apache Na Pasta Home

Muitas vezes quando configuramos um servidor para hospedar sites para diferentes usuários, a primeira coisa que pensamos é em colocar os sites de cada usuário na pasta home do mesmo, mas para isso funcionar corretamente precisamos dar permissão para o Apache ler a home de cada usuário. A solução que tenho usado é dar a seguinte permissão na pasta do usuário

chmod.sh
1
chmod a+x /home/nome_do_usuario/

Depois disso todos os “forbidden” desaparecem :)