Search code examples
opalrb

Opal.rb bridged class inner mechanics


I want to know how exactly bridging to native classes does internally work. (can't find any documentation on that).

function NativeClass() { this.foo = "bar"; } class MyClass <NativeClass; end

Is it similar to ES6's or coffeescript's inheritance (from JS perspective)?

Is it possible to define methods on function that can be called like regular ones (like:

RubyClass`.prototype`.foo = function(){return RubyClass instances' @accessor}) not the.$foo`.

And one more thing. If Ruby class is inheriting from native class, is it possible to reference in that function to the instance of Foo class that'll be instantiated, like function(){this.bar = Foo's instance}?

Is it possible to return native class from Ruby class (that inherited from native) (for example if some JS library needs native class as arg)?


Solution

  • Basically any Opal class is a full blown object instance of the class Class with some additional properties. The most relevant in this context are $$proto which holds the class' prototype and $$alloc which holds the original class constructor.

    Mapping the C-Ruby implementation #allocate will call $$alloc internally and Class#new will call in sequence #allocate and #initialize (just like regular Ruby).

    As of bridged classes are made building a full blown Class instance and injecting in the prototype and constructor of the native JS class. Then methods from BasicObject are copied over and (IIRC) Kernel is mixed in.

    For further details I suggest reading the relevant parts directly from the Opal source. When I did it I learned a lot! :)

    Some starting points are:

    • runtime.js in which the passed superclass is checked for being a function
    • class.rb the .new and #allocate methods from Class