Métodos privados semelhantes a Java/C++ em Ruby

Fazia um tempo que eu não postava uma das bizarrices em Ruby, então vamos lá: esses dias, no grupo de usuários de Ruby, surgiu uma discussão muito boa sobre métodos privados e alto acoplamento. A idéia é mais ou menos assim: em Java (ou C++), ao definir um método público que chama um método privado, se você reimplementar aquele método privado, os métodos públicos herdados não são afetados. Um exemplo vale mais que mil palavras, então:

#include <stdio.h>

class Example {
    public:
    void imprimir() {
        hello();
    }

    private:
    void hello() {
        printf("Hello, world!\n");
    }
};

class Ex2: public Example {
    private:
    void hello() {
        printf("Hello, from Ex2\n");
    }
};

int main(void) {
    Ex2 e;
    e.imprimir(); //Essa linha imprime "Hello, world!"
}

Já no código Ruby equivalente:

class Example 
  def imprimir()
    hello
  end

  private
  def hello
    puts "Hello, world!"
  end
end

class Ex2 < Example 
  private
  def hello
    puts "Hello, from Ex2"
  end
end

Ex2.new.imprimir #Imprime "Hello, from Ex2"

Ou seja, reimplementar métodos privados numa subclasse pode quebrar métodos da superclasse. Embora eu considere isso uma peculiaridade da linguagem e não como um problema de acoplamento, implementação falha, ou qualquer coisa (e até, mais pra frente, pretendo escrever um post sobre o assunto de diferenças entre linguagens de programação além da sintaxe), a discussão inteira me deu uma idéia: como implementar esse comportamento em Ruby?
(more…)

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…)

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…)

Programação Procedural em Java

Ok, o título parece estranho, mas é algo que me preocupa: Afinal, POR QUE as pessoas confundem tanto desenvolvimento orientado a objeto com procedural? Recentemente eu fiz uma integração do Jasper com Ruby (projeto Jasper on Rails, no meu github) e me vi tendo que usar a API do Jasper. É mais ou menos assim (em JRuby):

  modelo = "#{DIR}/arquivo.jasper"
  dados = File.read("#{DIR}/dados.xml")
  str_reader = java.io.StringReader.new(dados)
  input_source = org.xml.sax.InputSource.new(str_reader)
  documento = JRXmlUtils.parse(input_source)

  params = {
    JRXPathQueryExecuterFactory::PARAMETER_XML_DATA_DOCUMENT => documento
  }
  fill = JasperFillManager.fill_report(modelo, params)
  pdf = JasperExportManager.export_report_to_pdf(fill)
  return String.from_java_bytes(pdf)

(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…