Traçando a Execução em Bibliotecas de Terceiros (em Ruby)

Ontem, acredito que esbarrei feio num bug do Ruby 1.8 (não sei se outras versões estão com o mesmo problema). Para encurtar a longa história, estava mexendo num código usando TheRubyRacer semelhante ao seguinte (nota: se você não entender o código a seguir, vale a pena dar uma olhada em meu post anterior):

class UmaClasse
  def method_missing(method, *args, &b)
    puts "Método #{method} chamado!"
    ...
  end
end

require 'v8'
context = V8::Context.new
context['classe'] = UmaClasse.new
p context.eval('classe.um_metodo')
p context.eval('classe.um_metodo = 10')

O que eu esperava, é que na linha 11, fosse impressa a mensagem “Método um_metodo chamado!”, porém o que aconteceu não foi bem isso. Quando olhei para a documentação da biblioteca, descobri que ela expõe apenas os métodos públicos por padrão, agora COMO ela fazia isso… isso já é outro problema. Então, num primeiro momento, resolvi remover todos os métodos da classe UmaClasse, e ver o que acontecia:
(more…)

Conectando Javascript e Ruby

Bom, a algum tempo vi uma biblioteca chamada Harmony, para Ruby, que tenta fazer esse processo. Porém, eu achei alguns problemas na biblioteca que meio que me impediam de usá-la do jeito que eu queria, então acabei encontrando uma outra alternativa: The Ruby Racer.

Esta biblioteca usa o interpretador V8, o mesmo usado no Google Chrome, para interpretar Javascript. Possui uma API bem simples, e consegue incorporar objetos Ruby no Javascript de uma forma bem transparente. Como exemplo, digamos que queremos expor uma classe Ruby para o Javascript. Basta usar o código a seguir:

require 'v8'

class UmaClasse
  def initialize(nome)
    @nome = nome
  end

  def imprimir_nome
    puts @nome
  end
end

js = V8::Context.new
js['uma_classe'] = UmaClasse.new
js.eval('uma_classe.imprimir_nome()')

Este código conectará, no Javascript, um objeto chamado uma_classe. Para instalar a biblioteca, um simples “gem install therubyracer” basta, na maioria das vezes. Quando isso não funciona (que nem o meu caso)…
(more…)

Dá para fazer tipagem estática em Ruby?

Bom, resolvi começar uma série – coisas que você NUNCA quis fazer com Ruby, e tinha medo de perguntar. Basicamente, pensei em montar códigos absurdos de coisas que são completamente contra a filosofia da linguagem, ou que pelo menos são muito esquisitas, e publicar aqui os resultados. As regras são simples: os resultados devem ser testáveis (com RSpec, de preferência) e devem ser escritas puramente em Ruby, de preferência sem nenhuma biblioteca auxiliar (e, se for necessário usar, é obrigatório que a biblioteca tenha sido escrita puramente em Ruby também).

Como primeiro da série, vamos simular uma tipagem estática em Ruby. Como é impossível sobrescrever o operador “=” em Ruby, resolvi usar uma função – static – para simular o mesmo comportamento. Para simplificar, vamos meio que definir uma “variável global” com “static.”, e definir que esta terá tipagem estática. Começamos definindo uma função chamada “static”

def static
  Static.instance
end

(more…)

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…