Porque o Rubinius é importante.

Muita gente já falou sobre o assunto, e eu percebi, até agora, que não dei minha opinião então…

Para as pessoas que estão interadas, Rubinius é uma implementação de Ruby sobre Ruby. Parece estranho, e é um pouco mesmo, então vale a pena mostrar mais como isso funciona. Nos outros interpretadores, uma boa parte das classes padrão da linguagem são implementadas em C (ou Java, no caso do JRuby). Em Rubinius, estas classes são implementadas em Ruby sempre que possível, e a máquina virtual (VM, atualmente estão usando o LLVM) é extremamente simples e otimizada. Com isso, além de Ruby ficar muito mais flexível (mais? sim, é sempre possível) ainda se ganham alguns conceitos interessantes. Para fazer esta “mágica”, é necessário um compilador que traduz código Ruby para bytecodes que serão executados na LLVM – e Rubinius escreveu este compilador totalmente em Ruby. Pode parecer um conceito absurdo, mas não é – o próprio compilador C da Gnu, o GCC, é escrito em C.
(more…)

A saga da busca em bancos de dados

Num mundo perfeito, todos os sistemas de armazenamento se conversariam, a nível do servidor e não do cliente, e jamais precisaríamos manualmente definir por “joins”, ou seja lá qual a forma que seu banco de dados faz.

Claro, o mundo não é perfeito.

Nesse caso, precisamos no mínimo padronizar uma forma de buscar dados. A maioria dos sistemas relacionais entende SQL, embora isso também não seja padronizado. Pior ainda, se for necessário buscar uma informação que está em uma tabela da base de dados X, e uní-la (join) com uma da base de dados Y, temos que fazer a busca manualmente.

Entra, aí, uma idéia.
(more…)

Curiosidades sobre Procs em Ruby

Esses dias, estava montando um código para Ruby usando Procs (blocos de código), salvando esses procs em variáveis e depois rodando-os sobre “bindings” diferentes. Talvez tenha ficado um pouco complicado de entender, mas na prática é algo mais ou menos assim:

class UmaClasse
  def self.callback_qualquer
    ...#alguns códigos aqui....
    @@bloco = proc do
      break if condicao_qualquer
      ...#códigos do meu callback
    end
    ...#mais algumas coisas
  end

  def salvar
    instance_eval(&@@bloco)
    puts "Rodei"
  end
end

Ou seja, eu posso criar um bloco definindo um callbackqualquer, e depois rodar esse bloco no contexto da “instância”, não da classe (o código que eu fiz, na verdade, é bem mais complexo). Mas, surpreeendentemente, esse código não funciona – ele lança um LocalJumpError se a condição do Proc for satisfeita. Por quê?

(more…)

Paradigmas do MongoDB

Esses dias trabalhei firme no meu mapeador para MongoDB, o MongoParadigm. O código dele, como sempre, está disponível no GitHub. Atualmente estou me esforçando para integrar ele com Rails, e depois disso tudo pretendo finalmente implementar o “has :many” e o “belongs_to”. Pensei como seriam essas associações, e percebi que elas era a parte menos importante do MongoDB.

Isso porque eu acho que estou entendendo o que exatamente é uma base de dados orientada a “documentos”, finalmente – trabalhando na UFABC, é fácil de ver esse tipo de coisa: O registro de um aluno é um documento (no caso, de uma pessoa). O histórico do aluno é outro documento – e essa é a parte interessante, o histórico é um documento que pertence a um aluno, e não o contrário. Isso deve ficar bem documentado no MongoDB, porque apesar de não parecer, as bases de dados relacionais levam a gente a pensar de forma não-natural. Por exemplo, quando você vai armazenar um histórico de notas de um aluno em uma base relacional, normalmente você não armazena UM histórico, e sim um monte de registros que estão ligadas a um aluno por uma chave. Agora, é perfeitamente simples de entender porque o MongoDB não implementa trasações – afinal, no caso dele, se fosse necessária uma alteração se está mexendo em UM documento, e não em 20 registros, por exemplo.

(more…)

Usando frameworks Java com JRuby

Estes dias, estava vendo uns projetos antigos e lembrei de um framework bem legal para Java chamado ZK. O problema do ZK é que você consegue aproveitar o máximo dele quando você programa usando Servlets, e não usando o modelo ZUL dele. Lembrei de alguns projetos que fiz, de algumas coisas interessantes que ele fazia e também lembrei que eu cheguei a programar com Servlet em Ruby, e aqui vai como eu fiz mais esse trabalho para evitar Java. NOTA: Isso funciona com qualquer framework Java, seja ele ZK ou Echo2 ou qualquer outro, porque na verdade o que você faz é escrever algumas linhas de código de “cola” e depois passa o controle para o JRuby

A primeira coisa que você precisa é do JRuby instalado, e de um compilador Java. Crie seu projeto normalmente, e provavelmente você terá uma classe que será responsável por instanciar a primeira classe (janela, página, seja lá o que for) do seu Servlet. Nesse ponto que a “mágica” acontece. Para simplificar as coisas, que vou criar uma classe (chamada Inicial) que instanciará uma JFrame. Toda a JFrame será definida em JRuby.

(more…)

Jasper on Rails

Esses dias comecei a estudar como integrar algum sistema de relatório ao Rails. O problema principal é que nenhum sistema de relatórios possui editor visual (para Layout, essas coisas fazem uma diferença…). Felizmente, existe o Jasper, com o iReport que é um editor visual. O problema é que ele é Read more…

DataMapper versus ActiveRecord

Outro dia, tive um problema chatíssimo com o ActiveRecord: eu precisava criar um código de autenticidade, que conteria várias matrículas, que conteria várias disciplinas. O problema é o seguinte: Essas matrículas só seriam válidas se, por exemplo, o total de créditos das disciplinas não ultrapassassem um determinado número. Logo, resolvi fazer a validação no modelo de autenticidade, da seguinte forma:

class Autenticidade < ActiveRecord::Base
  MAX_CREDITOS = 40
  has_many :matriculas
  has_many :disciplinas, :through => :matriculas
  validate :credito_alto?

def credito_alto?
    total = disciplinas.inject(0) { |r, v| r += v.creditos }
    errors.add(:disciplinas, 'créditos acima do permitido') if total > MAX_CREDITOS
  end
end

class Matricula < ActiveRecord::Base
  belongs_to :disciplina
  belongs_to :autenticidade
end

class Disciplina < ActiveRecord::Base
end

Ok, o problema agora é o seguinte: Se eu crio uma autenticidade, com o parâmetro :disciplina_ids => [1, 2], por exemplo, e a autenticidade não é válida, nenhuma nova matrícula é criada – como deveria ser. Agora, se eu atualizo uma autenticidade, com o  autenticidade.update_attributes( :disciplina_ids => [1, 2]), e essa autenticidade não é válida, o ActiveRecord salva as matrículas. Nesse caso, eu tenho uma inconsistência na base de dados feia – e precisava encontrar uma alternativa que não envolvesse muitos hacks, coisa que ainda não encontrei. Mas isso me estimulou a pesquisar o DataMapper.

(more…)