Skip to content

Instantly share code, notes, and snippets.

@adambeynon
Last active December 27, 2015 01:49
Show Gist options
  • Save adambeynon/7248177 to your computer and use it in GitHub Desktop.
Save adambeynon/7248177 to your computer and use it in GitHub Desktop.
Method tables

Method tables

Stupid idea, but lets just look at the benefits/costs

We compile a ruby call currently as:

recv.$foo(1, 2, 3);

But, with method tables:

recv.$m.foo(recv, 1, 2, 3)

Downsides

  • ugly code (not anywhere near as bad as our old mm code)
  • slower (but only by about 10% - but we never* have to wrap js objects again?)

Benefits

  • Subclassing Array, String, Error, Numeric, JQuery etc just works - we just set the right $m property
  • Make any js object/dom object a ruby object by adding .$m property - no more Native?
  • ruby class is just a Function + prototype + we dont need classes to be anything special
  • no more infecting Arrays with 169 different methods - we only add 1 property $m
  • Arrays + jquery + others can all support method missing out of the box
  • No more wrapping - just add $m to any object
var el = document.getElementById("my_div");
el.$m = Opal.DomNode.$m_tbl;
el.inner_html = "foo"
el << other_dom_node

No wrappers!

What about Native()

module Kernel
  def Native(obj)
    %x{
      if (!obj.$m) {
        obj.$m = Opal.Native.$m_tbl;
      }

      return obj;
    }
  end
end

doc = Native(`window.document`)

puts(`doc === window.document`) # => true

first_foo = document.getElementById("foo");

class << doc
  def get_element(id)
    Native(`self.getElementById(id)`)
  end
end

doc.get_element "foo"

puts(`foo === first_foo`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment