Carlos Brando

Nome do Jogo

Acompanhe também Grok Podcast

Cinco anos de Nome do Jogo

8 de Fevereiro de 2012

[image]

A cinco anos atrás eu decidi escrever um blog com a finalidade de compartilhar meus estudos na área de desenvolvimento de software. Afinal, a melhor forma de aprender é ensinando. Confesso que escrever com uma boa regularidade não é uma tarefa fácil, mas nesses anos ter construído esse blog foi sem dúvida a melhor coisa que fiz pela minha carreira.

Embora nos últimos anos eu tenho lido mais livros e menos blogs, eu ainda considero esse meio de comunicação muito eficiente. É possível escrever um artigo de forma relativamente rápida e espalhar o conhecimento de uma forma que nem um Twitter ou livro são capazes de fazer.

Desse blog já saíram quase mil artigos, muitos vídeos, dois podcasts de sucesso, dois livros sobre Ruby on Rails (que foram traduzidos para 8 idiomas) e com o apoio de toda a comunidade a tradução do excelente Why’s (Poignant) Guide to Ruby. Sou muito grato aos meus fieis leitores e meu plano é continuar contribuindo para a formação de bons profissionais aqui e no Grok Podcast.

Mudanças no Ruby Inside Brasil

31 de Janeiro de 2012

Salve,

Há uns 3 anos o Carlos Brando resolveu trazer o Ruby Inside para o Brasil, a idéia era ser um site de notícias de Ruby que iria traduzir o conteúdo do site original do Peter Cooper e também publicar conteúdo nacional, tudo para ajudar a divulgar o Ruby e o Rails no Brasil, que até então só era utilizado por uma pequena comunidade.

Eu fui um dos primeiros editores e acabei tocando boa parte das traduções, buscando parcerias com outros sites e eventos e as coisas andaram bem, mas chegou um momento onde eu me peguei pensando: porque estamos fazendo isso? Lembro de uma conversa que tive com o Cássio Marques em alguma lista, a ruby-sp ou a rails-br, onde ele falava que traduzir conteúdo não ajudava muito a comunidade, ela tinha que crescer, aprender inglês e ler os originais, e que a tradução não ajudava nisso. Na época discordei, mas depois de um tempo concordei com a opinião dele, e acabei parando as traduções, e o site ficou parado, só uso a conta do Twitter para repassar notícias que acredito ser relevantes para a comunidade.

Hoje o Ruby cresceu muito no Brasil, temos vários grupos de usuários, só o Guru-SP reune por volta de 50 pessoas todos os meses para falar sobre Ruby e tecnologias relacionadas, e a comunidade continua crescendo. Temos várias empresas e consultorias que usam Ruby todos os dias, rubistas famosos no Brasil e no exterior, e talvez o Ruby Inside possa voltar a ajudar a comunidade, mas espero que de uma forma diferente.

No momento, não tenho tempo ou vontade de voltar a tocar o site, e não temos mais o corpo editorial do início, então é o momento de trocarmos a guarda. Esse post é um convite público à comunidade para conversarmos sobre o que se pode fazer com o site, achar gente que esteja disposta a tocá-lo e fazê-lo voltar a ser útil.

Deixo claro que não terei nenhum envolvimento no projeto, só quero passar a tocha, mas quero fazer isso de uma forma que ajude a comunidade. Aguardo seus comentários.

Atenciosamente,
Rafael Rosa Fu

Os interessados em assumir o projeto podem deixar um comentário nesse post preenchendo corretamente o campo de e-mail (que não aparece para todos). O Rafael Rosa entrará em contato.

Ruby em todos os lugares e dispositivos

7 de Novembro de 2011

Na última quinta e sexta-feira aconteceu em São Paulo o RubyConf 2011. O RubyConf é sem sombra de dúvida a melhor conferência nacional sobre programação na atualidade.

As palestras, como sempre, foram acima da média. E esse ano a organização deu um passo além transmitindo online todas as apresentações. Se você não pôde estar presente é possível assistir ao evento inteiro no site da eventials, a empresa encarregada pela transmissão e gravação do evento. Segue o link: http://www.eventials.com/rubyconfbr

Eu também tive a oportunidade de palestrar, junto com meu amigo Luis Gustavo, e dessa vez o assunto foi sobre a nova máquina virtual Ruby compacta que estamos desenvolvendo aqui na Plano Bê. Para assistir a minha palestra, clique aqui. Os slides estão abaixo.

Eu já participei de muitas conferências sobre Ruby e outras linguagens, mas nenhuma se compara a RubyConf. Eu sei que o custo envolvendo a entrada do evento, viagem, alimentação e outros pode ser um pouco pesado, principalmente se você está iniciando na área, mas vale cada centavo.

Grok Podcast Extra - O que você achou?

18 de Outubro de 2011

O RubyConf Brasil 2011 está chegando e o Grok Podcast vai te ajudar a participar do evento sem gastar um centavo. Estamos sorteando até sexta-feira 4 ingressos para o evento.

Para participar é fácil. Basta clicar aqui ou publicar a mensagem abaixo no seu Twitter:

Participe da #RubyConfBR by #Locaweb, saiba mais sobre o evento em http://goo.gl/K5gHh e concorra a 4 ingressos /via #GrokPodcast

Aproveite que está no Twitter e me siga em @carlosbrando. ;)

Esse episódio introduz um formato diferente. Episódios extras, fora da cronologia normal e patrocinados por uma empresa ou grupo. Não queremos em hipótese alguma fazer simples propaganda, pelo contrário somente conteúdo relevante e que agregue conhecimento serão aprovados para esse formato. Porém o patrocinador pode sugerir temas que estejam relacionados ao seu negócio.

Esse primeiro episódio é apenas um piloto. O objetivo principal do Grok Podcast é informar e compartilhar conhecimento e não necessariamente lucrar com isso, porém com o crescimento de nossa audiência nossos gastos tem aumentado muito e esses anunciantes nos ajudam a manter o podcast no ar.

Porém, nós estamos interessados em saber o que você achou desse piloto. Se você é um ouvinte, deixe um comentário dizendo como se sente em relação a esses episódios extras e quais as suas expectativas.

O mesmo vale caso você tenha interesse em anunciar na série regular ou patrocinar um episódio extra. Nesse caso, entre em contato através da nossa página de contato e explicaremos em mais detalhes como isso funciona.

Contratos onde todos ganham

12 de Setembro de 2011

Lidar com computadores não é fácil, por outro lado lidar com pessoas costuma ser ainda mais complicado. A muito tempo eu já me convenci que o relacionamento entre clientes e programadores sempre serão problemáticos.

A forma mais simples de tentar diminuir a tensão entre os lados envolvidos são os contratos.

Um bom contrato deve deixar claro quais são os direitos e responsabilidades de cada um dos envolvidos. Também não deve deixar dúvidas sobre qual será a repercussão no caso de uma das partes não cumprir com o acordo.

Um tipo básico de contrato é o que define um preço fixo para o projeto. Esse tipo de contrato é a melhor opção para o cliente e a pior para o programador. Uma mudança no escopo ou um pequeno atraso e tudo vai para a conta do desenvolvedor, deixando todo o risco nas mãos do profissional. Normalmente esse é o tipo de contrato que mais dá problema, já que o programador costuma se sentir lesado por alterações no escopo do projeto e o cliente não se sente na obrigação de pagar mais por isso.

Por outro lado um contrato de tempo e recurso, onde o cliente paga pelo tempo de cada profissional alocado no projeto é o melhor contrato para o programador, mas é o pior para o cliente. Nesse caso, atrasos e alterações no escopo caem sempre na conta do cliente, mesmo quando a culpa não é dele.

Para beneficiar ambos os lados, talvez o mais interessante seja unir esses dois tipos de contratos em um contrato híbrido, onde o cliente e o programador definem um valor fixo menor e uma taxa por horas de trabalho.

Funciona mais ou menos assim: se você estimar que serão necessárias aproximadamente duas semanas (80 horas) para finalizar o projeto e normalmente você cobra R$ 100,00 por hora, então o custo estimado para o projeto seria de R$ 8.000. Nesse tipo de contrato você definiria então com o cliente um pagamento fixo no valor de R$ 4.000 e mais uma taxa de R$ 50,00 reais por hora trabalhada no projeto.

Se o projeto terminar dentro do prazo, o cliente terá pago exatamente o valor estimado para o projeto e todos ganham.

Se o projeto terminar antes da data, o cliente terá pago menos e você terá ganho mais. Digamos que o projeto seja finalizado com 60 horas trabalhadas. Então o cliente pagará R$ 7.000 pelo serviço, que é menos do que o esperado. E você receberá R$ 1.000 a mais do que você receberia pelas 60 horas trabalhadas. Mais uma vez, todos ganham.

Por outro lado, se algo acontecer e o projeto atrasar, então o cliente estará pagando adicionalmente metade da sua hora, dividindo assim igualmente o risco entre o cliente e o programador.

Não importa se você usa uma metodologia ágil ou um modelo mais tradicional, contratos são essenciais em qualquer negocio e não será diferente em desenvolvimento de software. O importante é que você nunca feche um negócio sem assinar um antes.

Como convencer sua equipe a usar um sistema de controle de versão

25 de Agosto de 2011

Desenvolver software sem um sistema de controle de versão (ou SCM do inglês source code management) pode parecer irreal para muitos dos leitores desse blog, mas é importante esclarecer que muitas empresas e profissionais ainda não entendem o valor desse tipo de ferramenta.

Nota para o leitor: Se você não sabe o que é um SCM, recomendo ouvir a série sobre o assunto que gravamos recentemente para o Grok Podcast.

A situação fica ainda mais dramática quando um programador “iniciante”, porém esclarecido, trabalha em uma empresa que ainda armazena o código-fonte de seus projetos em um diretório no servidor ou somente no computador do desenvolvedor. Nesse caso, como convencer seus colegas de trabalho e principalmente o seu chefe que eles precisam adotar uma ferramenta para controlar o código?

A palavra-chave aqui é evangelização. Comece implementando o seu próprio SCM particular. Existem dezenas de opções open-source que podem ser instaladas localmente em sua máquina ou em um servidor da empresa que você tenha acesso. Essa iniciativa fará com que ao menos o seu código tenha uma certa medida de segurança, o que lhe trará um pouco de tranquilidade.

Com o tempo você, diferente de seus colegas, passará a ter a resposta para perguntas como: “Exatamente que alteração foi realizada no módulo XYZ?” e “Quem foi o responsável pela alteração que quebrou o software?”. É questão de tempo até que seu chefe e colegas se convençam das vantagens em adotar um sistema para gerenciar o código da sua empresa.

Ainda outra opção é fazer com que sua equipe ouça o Grok Podcast.

Blogando como um hacker

19 de Agosto de 2011

Depois que me acostumei a somente falar e a escrever em sentenças de 140 caracteres, blogar tem se tornado cada vez mais raro. Mas esse blog ainda é a menina dos meus olhos e de forma alguma ficará abandonado.

Embora editar o audio do podcast dê um certo trabalho, falar é muito fácil. Da mesma forma, enviar uma mensagem pelo Twitter também já se tornou algo natural. Mas escrever um texto para o Nome do Jogo ainda exigia um certo ritual que não me agradava muito, que basicamente envolvia acessar a interface do Wordpress, escrever o post, editar os trechos de código no TextMate e exportar para HTML, editar as imagens, etc..

Acostumado com ferramentas ricas e ao mesmo tempo simplistas, eu já estava decidido a mudar a engine desse blog e abandonar o Wordpress. Porém durante muito tempo não consegui encontrar uma ferramenta que justificasse o esforço da migração.

Recentemente eu adquiri uma cópia do excelente aplicativo iA Writer que é um editor de textos muito simples, que não possui nenhuma configuração e permite escrever usando a sintaxe do Markdown. É engraçado, mas me livrar da preocupação com a formatação do texto reativou o meu prazer em escrever.

Outra ferramenta importante nessa equação é o Octopress, uma engine baseada no Jekyll para a publicação de blogs. A simplicidade do Octopress me permitiu migrar todo o conteúdo do Nome do Jogo (quase mil artigos) rapidamente. O maior trabalho que tive na migração foi ajustar alguns textos, mas como tudo é baseado em arquivos: Regex to the rescue!

[image]

O que você está vendo agora é o novo blog Nome do Jogo, totalmente baseado no Octopress e com o tema padrão da ferramenta. Acredito que isso vai tornar muito mais fácil publicar meus artigos e certamente vai aumentar a freqüência de publicação.

A Regra Direita-Esquerda do C

13 de Junho de 2011

Atualmente estou envolvido em um projeto envolvendo módulos específicos em Ruby, Erlang e C. Ruby e Erlang são mais tranquilos, mas C tem a desagradável característica de deixar alguns códigos “meio” complicados de entender.

Porém, um colega da Plano Bê me enviou um artigo que me ajudou muito e quero compartilhá-lo com vocês. O artigo original parece ter sido escrito por Rick Ord da Universidade da California, em San Diego. Segue a tradução:

A Regra Direita-Esquerda do C

A regra direta-esquerda é muito útil para decifrar declarações na linguagem C e também pode ser de grande ajuda ao escrever código. A regra é bem simples, toda vez que encontrar os seguintes símbolos no código, leia:

*   como "um ponteiro para"      - sempre do lado esquerdo
[]  como "um array de"           - sempre do lado direito
()  como "uma função retornando" - sempre do lado direito

Passo 1

Encontre o identificador. Esse é o seu ponto de partida. Então, diga para si mesmo “o identificador é”. É nesse ponto que iniciamos a declaração.

Passo 2

Comece pelos símbolos a direita do identificador. Digamos que você encontrou um (), então você sabe que essa declaração é uma função. Então você deve dizer “o identificador é uma função retornando”. Caso você tenha encontrado um [], então você deve dizer “o identificador é um array de”. Continue avançando pela direita enquanto houver símbolos OU até encontrar um fecha parênteses ). (continue seguindo caso você encontre um abre parênteses, falaremos sobre isso mais abaixo.)

Passo 3

Quando terminarem os símbolos a direita do identificador, então comece a procurar por símbolos a sua esquerda. Se você encontrar algo diferente dos símbolos mencionados acima (digamos, algo como int), simplesmente repita o seu nome. Caso contrário, traduza o símbolo para o português usando a tabela. Continue seguindo pela esquerda enquanto houver símbolos OU até encontrar um abre parênteses (.

Então, repita os passos 2 e 3 até terminar toda a sua declaração. Veja abaixo alguns exemplos:

1

int *p[];


Encontre o identificador.
1
2
3

int *p[];
     ^
"p é"

Siga pela direita enquanto encontrar um símbolo ou abre parênteses.
1
2
3

int *p[];
      ^^
"p é um array de"

Quando não puder mais mover para a direita (os símbolo acabaram), então siga para a esquerda e encontre:
1
2
3

int *p[];
    ^
"p é um array de ponteiros para"

Continue seguinte pela esquerda e encontre:
1
2
3
4

int *p[];
^^^
"p é um array de ponteiros para int". 
(ou "p é um array onde cada elemento é um ponteiro para um inteiro")

Outro exemplo:

1

int *(*func())();


Encontre o identificador.
1
2
3

int *(*func())();
       ^^^^
"func é"

Vá para a direita.
1
2
3

int *(*func())();
           ^^
"func é uma função retornando"

Não dá para ir mais a direita devido ao fecha parênteses, então vá para a esquerda.
1
2
3

int *(*func())();
      ^
"func é uma função retornando um ponteiro para"

Não pode mais ir para a esquerda devido ao abre parênteses, então continue indo pela direita.
1
2
3

int *(*func())();
              ^^
"func é uma função retornando um ponteiro para uma função retornando"

Não dá mais para ir para a direita porque não há mais simbolos, então vá para a esquerda.
1
2
3

int *(*func())();
    ^
"func é uma função retornando um ponteiro para uma função retornando um ponteiro para"

E finalmente, o último símbolo a esquerda.
1
2
3

int *(*func())();
^^^
"func é uma função retornando um ponteiro para uma função retornando um ponteiro para um inteiro".

Como você pode ver, essa regra pode ser muito útil. Ela também é ótima para manter a sua sanidade enquanto estiver criando declarações, além de ajudá-lo a identificar onde colocar o próximo símbolo ou parênteses.

Algumas declarações podem parecer ainda mais complicadas quando definem o tamanho de um array ou informam uma lista de argumentos. Por exemplo, se você ver algo como [3], deve ler “um array (de tamanho 3) de…”. Mas se você ver algo como (char *,int), então deve ler “uma função esperando (char , int) e retornando…”*. Veja mais um exemplo:

1

int (*(*fun_one)(char *,double))[9][20];


Eu não vou seguir cada passo para decifrar essa declaração. Mas o resultado será: “fun_one é um ponteiro para uma função esperando (char , double) e retornando um ponteiro para um array (tamanho 9) de um array (tamanho 20) de inteiros”*.

Fica mais fácil se você remover o tamanho dos arrays e as listas de argumentos:

1

int (*(*fun_one)())[][];


Uma boa opção é decifrar dessa maneira e só depois adicionar o tamanho dos arrays e a lista de argumentos.

Algumas considerações finais

É totalmente possível criar declarações ilegais usando essa regra, então algum conhecimento do que é aceitável e do que não é em C é necessário. Por exemplo, se você tiver algo assim:

1

int *((*fun_one)())[][];


A declaração acima seria traduzida para “fun_one é um ponteiro para uma função retornando um array de arrays de ponteiros para inteiros”.

Uma vez que uma função não pode retornar um array, mas somente um ponteiro para um array, essa declaração é ilegal.

Combinações ilegais incluem:

[]() - não pode haver um array de funções
()() - não pode haver uma função que retorna uma função
()[] - não pode haver uma função que retorna um array

Em todos os casos acima, você provavelmente precisaria de um conjunto de parênteses para colocar um símbolo * a esquerda entre cada () e [] para tornar uma declaração válida.

Segue abaixo alguns exemplos válidos e inválidos para exercitar o que aprendemos:

int i;           "i um inteiro"
int *p;          "p é um ponteiro para um inteiro"
int a[];         "a é um array de inteiros"
int f();         "f é uma função retornando um inteiro"
int **pp;        "pp é um ponteiro para um ponteiro para um inteiro"
int (*pa)[];     "pa é um ponteiro para um array de inteiros"
int (*pf)();     "pf é um ponteiro para uma função retornando um inteiro"
int *ap[];       "ap é um array de ponteiros para inteiros"
int aa[][];      "aa é um array de arrays de inteiros"
int af[]();      "af é um array de funções retornando um inteiro (ILEGAL)"
int *fp();       "fp é uma função retornando um ponteiro para um inteiro"
int fa()[];      "fa é uma função retornando um array de inteiros (ILEGAL)"
int ff()();      "ff é uma função retornando uma função retornando um inteiro (ILEGAL)"
int ***ppp;      "ppp é um ponteiro para um ponteiro para um ponteiro para um inteiro"
int (**ppa)[];   "ppa é um ponteiro para um ponteiro para um array de inteiros"
int (**ppf)();   "ppf é um ponteiro para um ponteiro para uma função retornando um inteiro"
int *(*pap)[];   "pap é um ponteiro para um array de ponteiros para inteiros"
int (*paa)[][];  "paa é um ponteiro para um array de arrays de inteiros"
int (*paf)[]();  "paf é um ponteiro para um array de funções retornando um inteiro (ILEGAL)"
int *(*pfp)();   "pfp é um ponteiro para uma função retornando um ponteiro para um inteiro"
int (*pfa)()[];  "pfa é um ponteiro para uma função retornando um array de inteiros (ILEGAL)"
int (*pff)()();  "pff é um ponteiro para uma função retornando uma função retornando um inteiro (ILEGAL)"
int **app[];     "app é um array de ponteiros para ponteiros para um inteiro"
int (*apa[])[];  "apa é um array de ponteiros para um array de inteiros"
int (*apf[])();  "apf é um array de ponteiros para funções retornando um inteiro"
int *aap[][];    "aap é um array de arrays de ponteiros para inteiros"
int aaa[][][];   "aaa é um array de arrays de arrays de inteiros"
int aaf[][]();   "aaf é um array de arrays de funções retornando um inteiro (ILEGAL)"
int *afp[]();    "afp é um array de funções retornando um ponteiro para um inteiro (ILEGAL)"
int afa[]()[];   "afa é um array de funções retornando um array de inteiros (ILEGAL)"
int aff[]()();   "aff é um array de funções retornando funções retornando um inteiro (ILEGAL)"
int **fpp();     "fpp é uma função retornando um ponteiro para um ponteiro para um inteiro"
int (*fpa())[];  "fpa é uma função retornando um ponteiro para um array de inteiros"
int (*fpf())();  "fpf é uma função retornando um ponteiro para uma função retornando um inteiro"
int *fap()[];    "fap é uma função retornando um array de ponteiros para inteiros (ILEGAL)"
int faa()[][];   "faa é uma função retornando um array de arrays de inteiros (ILEGAL)"
int faf()[]();   "faf é uma função retornando um array de funções retornando inteiros (ILEGAL)"
int *ffp()();    "ffp é uma função retornando uma função retornando um ponteiro para um inteiro (ILEGAL)"

Colorific

3 de Junho de 2011

Já faz algum tempo que desenvolvi uma gem para imprimir o resultado dos meus testes de uma forma mais intuitiva, menos poluída e mais… colorida! Não sei bem porque, mas não divulguei muito essa gem na época. De qualquer forma, ai está:

[ http://www.youtube.com/embed/BQm4nFlJcco ]

Para instalar é fácil, basta adicionar o seguinte código no seu arquivo Gemfile:

1

gem 'colorific', :group => :test

Se desejar contribuir com algo, essa biblioteca tem 78 linhas de código apenas. E todo o código encontra-se no GitHub: https://github.com/carlosbrando/colorific/blob/master/lib/colorific.rb

Quem disse que gravar um podcast é fácil?

29 de Março de 2011

Não deixe de acompanhar semanalmente o Grok Podcast!

Artigos Recentes

Open Source

Atualizando…
@carlosbrando no Github

Últimos Tweets

Atualizando…

Bookmarks

Meus Bookmarks »

[image] Google+


You are viewing a mobilized version of this site...
View original page here

Mobilized by Mowser Mowser