Dá para criar classes abstratas em Ruby?

Ok, aqui vamos nós para mais estudos de como fazer coisas bizarras em Ruby… outro dia, estava olhando para um livro, “Design Patterns in Ruby”, que falava de classes abstratas (tipo Java) e a inexistência delas em Ruby, aonde “Duck Typing” resolve. Mas aí pensei: será que não dá para simular o comportamento de classes abstratas tipo Java, em Ruby?

Para os que não conhecem Java: se você, em Java, declarar uma classe como abstrata, e definir, digamos, dois métodos abstratos, quando esta classe for herdada, você é obrigado a definir estes dois métodos, senão o código sequer compila. Bom, parece então simples, em Ruby: basta criar uma classe, informar, de alguma que ela é abstrata, e então quando ela for herdada, se a classe herdada não definir todos os métodos, lançar uma exceção (digamos, um NoMethodError). Ok, Ruby permite traçar quando uma classe foi herdada com o método “callback” inherited, portanto é relativamente simples saber se a classe foi herdada e se ela implementa os métodos da abstrata, certo?

Bom, na prática… não.
(more…)

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…