Interface Gráfica com Ruby

Quando se pensa em Ruby, logo se imagina usando Rails. Na verdade, Ruby é uma linguagem completa com suporte a praticamente qualquer coisa. Todo programador Ruby sabe disso, mas esquecemos isso em nosso dia-a-dia.

Muitas pessoas usam várias GEMs para tentar automatizar qualquer coisa – e isso é bem errado. Por exemplo, há várias gems que tentam trazer o ActiveRecord para Sinatra, enquanto que na verdade, tudo o que temos que fazer é o código abaixo:

ActiveRecord::Base.establish_connection(
  adapter: 'sqlite3',
  database: 'some_database.sqlite3'
)

E é a mesma coisa com GUI (Graphical User Interface). Há uma série de gems que tentam trazer uma interface gráfica “fácil” para nós, que na verdade só acabam complicando tudo. Por isso, temos às vezes que simplificar o processo – que no caso de interfaces gráficas, para mim significa usar a gem qtbindings
Continuar lendo

Publicado em Ruby | Marcado com , , | Deixe um comentário

Experiências com o Atom

Para adicionar um pouco de fogo na velha “editor wars”, eu resolvi testar o SublimeText, Zed, e o Atom.

Antes, um disclaimer: eu sou um usuário VIM. Não um super usuário VIM – eu, por exemplo, uso as setas para navegar dentro de um arquivo (oh, o horror!), uso poucos plugins, enfim. Aí resolvi testar o SublimeText, e achei ele fantástico – rápido, estável, e funciona bem. Só tem um problema: 70 dólares.

Eu acho válido pagar por algo que você vai usar todos os dias. Mas 70 dólares é 1/3 de um Office. Já que eu tinha alternativas, resolvi testar o Atom. Antes disso, eu tinha feito um plugin para o Sublime, para rodar coisas pelo TMUX, e resolvi portar o mesmo aplicativo para o Atom, como um exemplo.

O Atom usa tecnologias web – HTML + CSS + JS + Node.JS para funcionar. Basicamente, plugins (e customizações do Atom) são escritos em Coffeescript ou Javascript, usando Node.JS, toda a interface do Atom, incluindo menus, abas, telas, são feitas usando HTML + CSS, você pode re-estilizar a tela toda usando LESS ou CSS, e os arquivos de config são em CSON ou JSON. O ponto negativo disso é que basicamente o Atom consome tanto de memória como o Chrome / Chromium, já que na verdade, ele basicamente É a mesma coisa – um browser rodando uma página. Há muitas vantagens na abordagem do Atom – a tela inteira do seu editor é customizável.

O veredicto final eu achei bom: eu acabei gostando do Atom. Ele é um pouco mais lento do que eu gostaria, e consome uns 300 – 400mb de memória na minha máquina (o que é bem ruim na verdade para pessoas que tem máquinas com pouca RAM) . Outra coisa que é perceptível é a facilidade de se fazer plugins (há um “scaffolding” de plugins no Atom) e quão fácil é integrar dependências externas, testes dos próprios plugins, etc. O ponto baixo sempre será o consumo de memória e de disco, que o Atom simplesmente precisa melhorar – e muito.

Sobre cada um dos detalhes:

Continuar lendo

Publicado em Sem categoria | Marcado com , , , , | Deixe um comentário

“Copiando” um Linux

Esses dias, um amigo meu comprou um SSD para o notebook dele, e queria copiar o Linux dele para o SSD. O detalhe, ele não queria instalar o linux novamente, e queria manter o diretório /home dele no HD antigo. Depois de fazer o processo, resolvemos que seria uma boa idéia postar sobre como fazer isso.

Inicialmente, é importante falar (para quem não conhece direito) que o Linux tem uma estrutura de diretórios bem peculiar. Todos os dados pessoais estão apenas no diretório /home, as informações de boot estão no diretório /boot, e outras informações estão em outros lugares. Logo, tudo o que se precisa fazer é mover os diretórios para o novo HD (no caso, o SSD) e deixar o diretório /home no HD antigo. Mas tem um pouco mais do que isso.

Continuar lendo

Publicado em Infra estrutura e SO | Marcado com , | Deixe um comentário

Como Comprar um Notebook

O post de hoje será mais uma conversa sobre a experiência de ter comprado um computador novo do que um post técnico mesmo.

Hoje em dia, não é mais fácil descobrir a velocidade de um processador somente olhando para o nome ou as especificações dele. Da mesma forma,  temos diversos fatores que devem ser pensados na compra de uma máquina seja para trabalho, jogos, ou simplesmente para uso no dia a dia. Comecemos então com as marcas:

Em primeiro lugar, é bem difícil identificar se um computador é bom ou não apenas por fotos ou pessoalmente: isso deve ser um trabalho de pesquisa, muitas vezes intensa. Quando estamos pesquisando, é comum pensarmos em marcas como HP, Dell, ou semelhantes como idéia de “marcas confiáveis”. Às vezes, erramos feio usando esse pensamento. Então, vamos pensar de outra forma: para que será usada a máquina?
Continuar lendo

Publicado em Divagações | Marcado com , , , , , , , | Deixe um comentário

Evitando o null-driven-development

Quando a programação em C estava em alta, havia uma série de alocações e liberações de memória. Depois disso, a alocação/liberação passou para C++, e a partir daí tínhamos código como o seguinte:

Person *person = new Person();
delete person;

Algumas vezes, queríamos criar um objeto mas não tínhamos todas as informações dele. Era comum usarmos o ponteiro e só atribuir ele quando tivessemos a informação:

Person *person = null;
//do something in-between
person = new Person(name);

Isso causava um efeito estranho que, eventualmente, o objeto seria “nulo”, ou “não existente”. Isso era uma novidade até o momento, já que nas linguagens mais antigas (VB, QuickBasic, Pascal, etc) ou não havia esse conceito de “nulo” ou não era comum usar.

Quando as linguagens orientadas a objeto dominaram o mercado, esse “null-pattern” acabou também entrando no mercado. Em Java (e Scala), por exemplo, qualquer operação que envolva um null lança um “Null-pointer exception” (que muitos programadores simplesmente capturam com um try-catch, mandam imprimir no console o stacktrace, e continuam o programa, que normalmente para de funcionar). Em Ruby, as coisas são mais complexas…

Ruby é a primeira linguagem que eu conheço que meio que “institucionalizou” o uso de nulos.
Continuar lendo

Publicado em Ruby | Marcado com , , , , | Deixe um comentário

SQL Orientado a Objetos

O nome parece estranho, mas um ORM, dependendo de como ele for implementado, pode ser usado exatamente para isso.

Estou trabalhando numa lib em Scala chamada relational, na qual eu pretendo fazer um SQL inteiro virar um objeto Scala. Mais ou menos o que o Arel tenta fazer, porém de forma esquisita (meio compatível com Rails, meio compatível com álgebra relacional, e não 100% nada). Mas isso fica pra um outro momento…

No post anterior, eu falei bastante sobre SQL, e sobre todas as coisas que podemos fazer ao saber montar uma query. A idéia agora é tentar montar, de fato, uma query, mas com mais do que apenas fragmentos SQL, mas com o próprio ORM.

Vamos pensar que temos uma tabela de usuários, e uma de números de telefones. O número pertence a um usuário, um usuário tem muitos números de telefone (nada de “join-tables” e coisas mais complexas por agora). Digamos que eu queira saber números de telefone possuem o mesmo prefixo (os primeiros quatro números-vamos ignorar, por hora, os nono dígito para deixar o código mais fácil) de um determinado número.

A idéia, num primeiro momento, é fazer o código para um único número. Vamos, por simplicidade, deixar isso na classe de Telephone mesmo:

class User < ActiveRecord::Base
  has_many :telephones
end

class Telephone < ActiveRecord::Base
  belongs_to :user
  
  def self.same_prefix_of(telephone)
    where('SUBSTR(telephones.number, 0, 5) = ?', telephone.number[0...4])
  end
end

#Para usar:
Telephone.same_prefix_of(Telephone.first)

Por hora, tudo bem. Um código simples, porém é agora que a coisa começa a ficar divertida: generalização
Continuar lendo

Publicado em Banco de Dados, Ruby, SQL | Marcado com , , , , | Deixe um comentário

Programadores Precisam Aprender SQL!

De uns tempos para cá, tenho vistos muitos códigos bizarros acontecendo no mundo dos ORMs, que eventualmente me deixaram pensando: será que ORMs estão fazendo-nos esquecer como se faz SQLs?

No mundo Ruby/Rails, virou quase uma regra não-escrita que escrever SQLs na mão é errado. Quanto mais pudermos aproveitar o ActiveRecord (e algumas mágicas que ele faz por nós), melhor. Isso acaba trazendo algumas coisas bem esquisitas, tal como achar que 90% dos códigos nunca vão precisar de “OR” (e maior, menor, diferente, etc), já que a API do ActiveRecord não suporta isso, ou algumas outras práticas meio estranhas. Do outro lado, temos por exemplo o framework “Play!”, de Scala, que faz o extremo oposto: não usa nenhum ORM, e todas as queries SQL passam a ser feitas na mão…

O ponto é que quando temos um ORM, parece que abusamos dele e esquecemos que nem tudo é um “SELECT * FROM <table> WHERE <attribute> = <value>”. Por exemplo, no código abaixo:

users = User.all
users.each do |user|
  puts "User #{user.name} has #{user.addresses.count} addresses"
end

Temos o famoso caso do “N+1″: 1 busca para achar N usuários, e a partir daí “N” buscas para achar a contagem de endereços. O problema é que muita gente acha que apenas um “User.include(:addresses)” resolve o problema, quando na verdade não resolve: o “include” vai trazer todos os endereços, mas a contagem (se o Rails optar por usar “count”) vai continuar sendo feita em banco, ou então (se o Rails optar por não usar “count”) será feita em Ruby, e teremos trazido registros a mais do banco de dados sem necessidade. A solução, nesse caso, é usar um comando SQL mesmo:

users = User.all
num_addresses = Address.join(:user).group('user.id').count
users.each do |user|
  puts "User #{user.name} has #{num_addresses[user.id]} addresses"
end

Ok, mas SQL é difícil, chato, e é mais fácil fazer as coisas em Ruby, certo? Bom, sim e não. É mais fácil fazer os comandos em Ruby (ou na linguagem que você escolher) puramente por “costume”. Estamos acostumados a fazer a sequencia: buscamos uma lista, tratamos a lista, exibimos a lista. SQL não trabalha com “listas”, mas com “conjuntos”. E é isso que vamos ver a seguir:
Continuar lendo

Publicado em SQL | Marcado com , , , , | Deixe um comentário