Calling Jank from C

For those that don’t know, Jank is a Clojure implementation but instead of targeting Java, it targets LLVM (Low-Level Virtual Machine). That means, Jank compiles to native code, and interops directly with C++.

Jank already have ways to call C++, but I wanted to do the opposite – to call Jank’s code from C. The reason might not be obvious, so here is an why: writing libraries.

Not all things need to be “stand-alone executables”. One example is libraries for Node, for Ruby, or Python. These languages are amazing on the levels of abstraction they support, and it’s easy to interact directly with code and their runtime (in Node, using Devtools, in Ruby, using something like pry or Lazuli, my own plug-in). They are also quite slow, and in some cases, we might need to call some native API that these languages don’t support. So what now? The canonical way is to write some extension in C or C++; now we have to manually manipulate memory and deal with safety issues (and before people say something about it “not being that hard”, it is. Most of CVEs happen because of manual memory manipulation in C – every cast, every printf, every strcpy can cause ACE and/or privilege escalation issues). They are also not interactive so if you’re trying to easily hack some solution, you need to write the code, compile, make a shared library, use the library via the Ruby/Node/Python code, see if it does the thing you want, repeat.

It’s tedious. Maybe with Jank we can speed up this process?
(more…)

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