Opal

Become ruby developer once again

Who am I?

  • Andrius Chamentauskas
  • Ruby developer for 8 years

Or am I?

4 stages of javascript

  1. Don't really know anything about it
  2. Maybe you can make some nice things with it
  3. You can actually write software with it
  4. There's got to be something better

Coffeescript

  • Syntax sugar
  • Polishing a turd
  • New problems

We can be saved!

Introducing Opal

  • Ruby > JavaScript compiler
  • Runtime for corelib and stdlib
  • Optional support for method_missing, const_missing, arity check
  • Mostly maps to native objects
  • Supports most of ruby 1.9
  • Immutable strings, string == symbol and some other gotchas

Calling natives

  • Call js using
    `#{1} + 1`
  • Local variables
    `num + 1`
  • Classes
    `Opal.SomeNamespace.SomeClass`
  • Methods
    `obj.$method()`
  • Instance variables
    `obj.instance_variable`

Debugging

  • Source maps
  • p/puts
  • `console.log(#{object})`

Size matters

Minified Gzipped
Opal Runtime 148KB 35KB
Sugar.js 49KB 18KB
Underscore.js 14KB 5KB

Greenspun's tenth rule

Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.

Greenspun's tenth rule

Any sufficiently complicated Javascript program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Ruby.

Opal & rails

  • Asset pipeline integration through *.js.rb or *.js.opal
  • .opal templates
  • HAML filter
  • Access to @controller_instance_variables

Opal rspec

  • RSpec for opal
  • *_spec.rb.js inside assets/javascripts/spec
  • rake or browser
  • Support for async specs

Opal & jQuery

Document.ready? do  el = Element['#id']  el.value = 'my input'
  el.on(:click) do |e|
    e.prevent_default
    el.add_class('clicked')
  end
  HTTP.get("/users.json") do |response|
    if response.ok?
      puts response.json
    else
      puts response.body
    end
  endend

Other JS libraries

Call native JS
`el.resizable({
  helper: "ui-resizable-helper"
});`
or write your own adapter
class Element
  def resizable(options = {})
    `this.resizable(#{options})`
  end
end

Vienna

  • MVC framework
  • Inspired by backbone
  • Still under development
  • Poor documentation

Build your own - View

class MyView < View  template :li do
    div model.name, class: 'name'
  end
  on :click do
    model.name = 'Opal'
  end
  render do
    el.resizable
  end
  def initialize(options = {})
    super
    model.on(:change) { render }
  endendElement['#container'].append MyView.new.render

Build your own - Model

class MyModel < Model  string :name
  integer :age
  embeds :children, MyCollectionend
class MyCollection < Collection
  child ChildClass
end

Interesting facts

  1. Not a single ; was used
  2. Not a single "self = this" was used

Other projects

  1. opal-irb
  2. opal-node
  3. meteor.rb anyone?

Conclusions

  • Ruby = awesome
  • Opal = Ruby
  • Opal = awesome
  • Questions?