Olá, eu sou o Jônatas, sou sócio da invent.to e sou full stack developer na Resultados Digitais.

ps: Sinta-se livre para conversar comigo por email ou gtalk: jonatasdp@gmail.com.

Vida de bike

Felizmente não estou escrevendo mais um capítulo da minha vida de busão pois comprei uma bike :)

Menos de um mês andando e fiz 452 km. Também já senti que vou ficar viciado no strava e estou muito empolgado com minha nova vida de ciclista.

Têm chovido quase todos os dias em Florianópolis então não consegui ir todos os dias pra Resultados Digitais de bike. Ainda caí um tombo leve e torci o pé acabei ficando uns 5 dias sem pedalar. Mesmo assim já tenho história pra contar \o/

Pedalada para o trabalho

Basicamente minha pedalada para o trabalho vai do Campeche ao bairro João Paulo e consigo ir em média em 1 hora, enquanto estava levando em média 30 minutos a mais de ônibus.

Agora, a RD está migrando para o lado do Floripa Shopping no bairro Monte Verde então hoje foi o primeiro dia que fui e ganhei mais 5 km então estou fiz 29 km para ir pela Beira mar norte em 1 hora e 25 minutos com vento sul contra. E para voltar foi 1 hora e 12 minutos.

Trajeto casa trabalho no strava

Uma das coisas que mais me empolgou logo no primeiro dia que peguei a bike foi a possibilidade de andar na planície pela beira do mar. Acostumado a chutar pedra e morro pra qualquer lado no sudoeste do Paraná e no extremo oeste catarinense, agora consigo andar uma boa parte da ilha sem subir e descer morro frenéticamente.

Por exemplo, a elevação máxima no meu trajeto é 47 metros em 29 km de extensão.

Trajeto casa trabalho no strava

Claro que estou fazendo um trajeto fácil porém mais longo, mas têm outras possibilidades "com morro" em Florianópolis que poderia me polpar em alguns quilômetros na rota.

Outra aspecto legal é que consigo pegar a maior parte do trecho com ciclovia então por mais que em algumas partes a ciclovia não é boa, pelo menos corre menos risco do que no trânsito direto com os carros.

Também concluí que se ainda estivesse morando no Ingleses não iria conseguir vir de bicicleta pois a SC 402 não tem ciclovia na maior parte então eu não iria me expor a este risco diário. Espero que em breve tenha mais e mais ciclovias.

Mas só pedalando pra ver

Mas nem tudo são flores pois a ciclovia ainda é extremamente vista como um estacionamento rápido e o ciclista passa despercebido pela maioria dos motoristas. Têm que ficar atento o tempo todo quando está nas ciclovias gambiarras ou quando não tem ciclovia.

Por exemplo: O trecho Rio Tavares -> Campeche, é um dos piores trechos pra se fazer de carro. De bike, existe uma ciclovia compartilhada com a calçada pois não houve espaço suficiente para as calçadas e a ciclovia. Então fica apertado e a têm muitas lojas e comércios locais onde o acesso é via ciclovia, e as pessoas usam pra colocar alguma coisa, ou mesmo parar um carro "rapidinho".

Além disso esquecem totalmente dos ciclistas e da ciclovia então tem que ficar na defensiva e tomar muito cuidado.

Já aqui dentro do bairro Campeche a ciclovia é melhor porém tem muita areia na ciclovia. Sinceramente não sei quando acontece a manutenção da ciclovia pois cheguei a 3 meses no bairro, mas têm muitos lugares em que existe um perigo sério de cair de tanto que os pneus atolam na areia da ciclovia :(

Reflexões da pedalada

Estou apreciando a vista.

Fiquei muito feliz em começar a ir com minha própria energia até o trabalho.

Imaginar que fiz 452 km em aproximadamente 3 semanas e polpei de queimar 45 litros de combustível em algum carro ou horas e horas mórbidas no ônibus me empolgou muito.

Me faz pensar que sou livre e posso pedalar muito mais. Possivelmente a bicicleta se tornará meu meio de locomoção principal.

Além de ajudar diretamente na minha saúde, exige de concentração, energia física e coordenação motora.

Também posso aproveitar muito mais a paisagem! E Florianópolis têm muitos lugares lindos pra mim bicicletar!

Estou redescobrindo minha paixão pela bike. Exatamente como aconteceu quando eu era criança :)



Rails Rumble 2015

Este ano participei novamente do Rails Rumble e foi muito legal! Minha terceira participação!

Estava solo até na quinta-feira um dia antes do evento e consegui converter o @efmiglioranza para o time na RailsRumble :]

Não trabalhamos nem próximo das 48 horas mas deu pra marcar presença e apresentar a ideia.

Trata-se de um jogo de verdadeiro ou falso com 5 segundos para o jogador "compilar" pequenas expressões de programação.

torf

Inicialmente tinha focado apenas nas questões em Ruby, mas depois como já estava usando o therubyracer e tava fácil pra compilar em js então resolvi seguir na mesma linha criando uns desafios em javascript.

Usei bastante as ideias do vídeo Wat by Gary Bernhardt:

E me empolguei nas gambiarras inusitadas do JS, no meio da competição acabei esbarrando no WTFJS by Brian Leroux e tive que fazer pra javascript também.

Então foi bem legal usar a mesma lógica do jogo de pequenas expressões para js e ruby.

torf js

Jogue com algumas das piadas js que a gente coletou por ae.

Ou desafie-se em 5 minutos de ruby easy :)

Fiquei chateado por não termos um designer e colocar uma interface mais interessante e atrativa.

torf

O que foi mais legal foi que consegui fazer o deploy ainda no sábado de tarde com as primeiras fazer logo na tela principal então tivemos mais de 170 acessos com um engajamento de 6 minutos.

Se você não jogou ou não viu acesse: http://torf.r15.railsrumble.com/ ou http://torf.ideia.me.

Deixe seu feedback sobre o game na thread da competição:

http://railsrumble.com/entries/136-true-or-false-are-you-really-a-compiler

Sinta-se livre para contribuir com novas fases ou criar seu game a partir da estrutura. O código opensource está aqui:

https://github.com/railsrumble/r15-team-136

E você participou? Não? Gostou? Deixe seus comentários sobre o evento!



Coffeescript rocks

Eu sou um fã de CoffeeScript e gostaria de mostrar alguns exemplos que me fazem lembrar que nunca mais vou escrever nenhuma linha de javascript puro.

Primeiramente eu não gosto de ficar repetindo as coisas e coffee é tudo de bom pra fazer isso. No javascript tem um monte de parênteses e chaves arbitrários porém acabam sendo mais chatos e deixam o código um pouco mais denso.

Coffeescript é uma linguagem que idealiza várias ideias que me atraem.

  • Simplicidade
  • Confidência
  • Minimalismo

Vou citar caso a caso as coisas que mais gosto. Todas elas são complementares e ajudam a manter a facilidade. Coffeescript é javascript. Logo tudo que estou fazendo é usar o transpilador para gerar o código final em js.

Se você curtir, vai copiando e colando os exemplos no j2.coffee.

Função

Em javascript teríamos:

maisUm = function(n) { n + 1 }

Em coffeescript temos:

funções

Então não precisa de function nem {}:

maisUm = (n) -> n + 1

Indentação inteligente

As chaves não são substituídas por um código indentado. Isso quer dizer que você vai usar espaços ao invés de chaves para todos lados.

maisUm = (n) ->
  n + 1

Se a função for complexa a identação vai expandindo e fica fácil de entender o contexto.

parOuImpar = (n) ->
  if n % 2 is 0
    'par'
  else
    'impar'

Também é possível fazer inline com then.

parOuImpar = (n) -> if n % 2 is 0 then 'par' else 'impar'

Essas opções inline são muito interessantes para explorar pois elas podem ser combinadas e gerar um código bem compacto e com bastante significado.

Por exemplo, vamos combinar a função de par ou impar para iterar sobre um array:

classificarParOuImpar = (array) ->
  for n in array
    if n % 2 is 0
      'par'
    else
      'impar'

Inline

A função acima, irá retornar um array de strings 'par' ou 'impar'. Se fosse escrever inline seria:

classificarParOuImpar = (array) -> if n % 2 is 0 then 'par' else 'impar' for n in array

Multiplas atribuições

As múltiplas atribuições já existem no javascript e não há nada de novo nisso. No entando o coffeescript tem a sua própria maneira de fazer.

Isso é muito interessante o quão simples torna as atribuções. Exemplo de atribuição sequencial:

a = 1
b = 2

Então em uma linha atribuindo múltiplas variáveis ao mesmo tempo:

[a,b] = [1,2]

Multiplas atribuições de hashes

As atribuições também funcionam para hashes.

Esse é um dos meus preferidos, principalmente pela simplicidade de extrair atributos. Imagina o seguinte código:

peso = pessoa.peso
altura = pessoa.altura
idade = pessoa.idade

Escrevendo em uma linha:

{peso, altura, idade} = pessoa

Agora, se você estiver super empolgado após usar as variáveis acima e quiser retornar um hash modificado com as medidas normalmente iria fazer:

{peso: peso, altura: altura, idade: idade}

Mas você pode simplificar ainda mais usando a seguinte sintaxe:

{peso, altura, idade}

Eu acho interessante a ideia de ter apenas uma maneira de se escrever um código mas gosto dessas variações que simplificam e minimizam a linguagem em si.

Acredito que as declarações como {a: a, b: b} são repetitivas e desnecessárias: Entendendo que {a,b} irá gerar exatamente isso, consigo manter um código mais limpo e menos verboso. Eu sinceramente gosto muito disso.

Parâmetros se transformando em atributo de acesso

Em um exemplo simples poderia escrever:

class Pessoa
  constructor: (nome) ->
    @nome = nome

Eu posso simplesmente usar @ no parâmetro e funciona da mesma maneira, criando o atributo interno do objeto.

class Pessoa
  constructor: (@nome) ->

E você não está limitado a usar apenas no constructor, pois pode usar onde bem entender este tipo de método e pode ser extremamente útil.

class Pessoa
  constructor: (@nome) ->
  indiceMassaCorporal: (@altura, @peso) ->
    @imc = @peso / (@altura * @altura)

Desta maneira eliminamos uma série de códigos repetitivos e verbosos.

||= atribuições condicionais

Uma possível melhoria para fazer no algorítmo acima, ainda seria evitar recalcular o imc se já foi calculado, cacheando o imc, ou recalculando:

class Pessoa
  constructor: (@nome) ->
  indiceMassaCorporal: (@altura, @peso) ->
    @imc ||= @peso / (@altura * @altura)

O exemplo é tosco mas apenas seguindo a linha de usar cache para o cálculo e evitar reprocessamento.

Condicionais?

Estilo narrador do polishop:

  • Transtornado com propriedades não definidas?
  • Recebe um undefined is not a function a cada tentativa de rodar um novo código?

Seus problemas acabaram! O super poder das condicionais no coffeescript é muito simples e fácil de usar! E se você comprar agora ainda pode levar inteiramente grátis as opções de trabalhar com condicionais encadeadas!

Veja com seus próprios olhos essa beleza em funcionamento:

if pessoa?
  pessoa.indiceMassaCorporal(190,112)

Também pode ser condicional inline.

pessoa?.indiceMassaCorporal(190,112)

E encadeado. Por exemplo, verificar se existe a função indiceMassaCorporal antes de executá-la:

imc = pessoa?.indiceMassaCorporal?(190,112)

No fim das contas detalhes como estes acabam poupando algumas linhas e o código fica extremamente fácil de entender.

Além disso dá pra usar uma série de funções anônimas inline e outros detalhes que realmente fazem o coffeescript ter seu brilho próprio.

Entre eles eu destaco: Tudo está sendo retornado no coffee. Então qualquer expressão é inline e pode ser re-utilizada.

Cada for é um map e está retornando o array da expressão interna. Então, você pode declarar um código como:

imcsDeVariasPessoas = pessoa.imc for pessoa in pessoas

Detalhes difíceis e cruéis

Nem tudo são flores e você vai precisar pisar em ovos no coffee também. Uma das maiores enrascadas do coffeescript está no @ e a falta de sabedoria na hora de usar ele.

Um bom conselho que posso dar é: mantenha-se sempre olhando o código javascript gerado pois você está compilando javascript e no final não pode gerar incompatibilidades da linguagem.

O @ é o this. do javascript. Então, ao se referir a uma propriedade você naturalmente usa @. Supomos o exemplo:

euclidean = (p1, p2) ->
  [a, b] = [p1.x - p2.x, p1.y - p2.y]
  Math.sqrt Math.pow(a, 2) + Math.pow(b, 2)
class Pessoa
  distancia: (outro) -> euclidean(@,outro)
  amigosProximos: (raioEsperado = 50) ->
    proximos = []
    @relacionamentos.filter (pessoa) ->
      if @distancia(pessoa) < raioEsperado
         proximos.push pessoa.nome
    proximos

Esse é o clássico algorítmo que não funciona e você fica puto da cara com isso.

Então é necessário entender o código gerado e você vai perceber que o @distancia não existe naquele contexto. Nesse caso, não existe pois uma função interna que faz o código do filter funcionar. Veja o código javascript gerado:

var Pessoa, eu, euclidean;

euclidean = function(p1, p2) {
  var a, b, ref;
  ref = [p1.x - p2.x, p1.y - p2.y], a = ref[0], b = ref[1];
  return Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
};

Pessoa = (function() {
  function Pessoa() {}

  Pessoa.prototype.distancia = function(outro) {
    return euclidean(this, outro);
  };

  Pessoa.prototype.amigosProximos = function(raioEsperado) {
    var proximos;
    if (raioEsperado == null) {
      raioEsperado = 50;
    }
    proximos = [];
    this.relacionamentos.filter(function(pessoa) {
      if (this.distancia(pessoa) < raioEsperado) {
        return proximos.push(pessoa.nome);
      }
    });
    return proximos;
  };

  return Pessoa;

})();

Criando a referência self

class Pessoa
  distancia: (outro) -> euclidean(@,outro)
  amigosProximos: (raioEsperado = 50) ->
    proximos = []
    self = @
    @relacionamentos.filter (pessoa) ->
      if self.distancia(pessoa) < raioEsperado
         proximos.push pessoa.nome
    proximos

Neste caso, o mais legal é usar a solução clássica de usar list comprehensions que é uma maneira simples e padrão do que manter-se usando uma variável self.

Mas segue de exemplo com self acima e abaixo com list comprehensions.

euclidean = (p1, p2) ->
  [a, b] = [p1.x - p2.x, p1.y - p2.y]
  Math.sqrt Math.pow(a, 2) + Math.pow(b, 2)
class Pessoa
  distancia: (outro) -> euclidean(@,outro)
  amigosProximos: (raioEsperado = 50) ->
    pessoa for pessoa in @relacionamentos when @distancia(pessoa) < raioEsperado

Então observando o exemplo final e o código gerado, escrevemos 7 linhas de coffeescript que geraram mais de 30 em javascript.

Observe o código final:

var Pessoa, euclidean;

euclidean = function(p1, p2) {
  var a, b, ref;
  ref = [p1.x - p2.x, p1.y - p2.y], a = ref[0], b = ref[1];
  return Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2)); };

Pessoa = (function() {
  function Pessoa() {}

  Pessoa.prototype.distancia = function(outro) {
    return euclidean(this, outro);
  };

  Pessoa.prototype.amigosProximos = function(raioEsperado) {
    var i, len, pessoa, ref, results;
    if (raioEsperado == null) {
      raioEsperado = 50;
    }
    ref = this.relacionamentos;
    results = [];
    for (i = 0, len = ref.length; i < len; i++) {
      pessoa = ref[i];
      if (self.distancia(pessoa) < raioEsperado) {
        results.push(pessoa);
      }
    }
    return results;
  };

  return Pessoa;

})();

E aí gostou? Tenta rodar na prática esse exemplo e não deixe de comentar!

Quais são suas principais dificuldades com coffeescript?

Confesso que apanhei e também sofri muito pois foi a primeira vez que trabalhei com uma linguagem que obriga a seguir uma indentação, mas no final têm sido ótimo, valendo muito a pena.

Sabemos que o javascript pode sofrer alterações drásticas, e a comunidade vai manter a compatibilidade.

Então de certa forma é até mais confortável usar coffeescript do que manter adaptando e readaptando o código para rodar na especificação mais recente e retro-compatibilizado.

Pense nisso! o/