Opal: The Journey from JavaScript to Ruby

Opal: The Journey from JavaScript to Ruby

Slide-deck from my presentation at RubyConf Kenya 2017.

1be785d1d788b82929e55fc83a9f0aaa?s=128

Bozhidar Batsov

June 11, 2017
Tweet

Transcript

  1. 4.
  2. 5.

    Bug

  3. 7.
  4. 9.
  5. 10.
  6. 13.
  7. 14.
  8. 18.
  9. 19.

    Ruby 2.2 includes many new features and improvements for the

    increasingly diverse and expanding demands for Ruby. For example, Ruby’s Garbage Collector is now able to collect Symbol type objects. This reduces memory usage of Symbols; because GC was previously unable to collect them before 2.2. Since Rails 5.0 will require Symbol GC, it will support only Ruby 2.2 or later. (See Rails 4.2 release post for details.) Also, a reduced pause time thanks to the new Incremental Garbage Collector will be helpful for running Rails applications. Recent developments mentioned on the Rails blog suggest that Rails 5.0 will take advantage of Incremental GC as well as Symbol GC.
  10. 20.

    Ruby 2.2 includes many new features and improvements for the

    increasingly diverse and expanding demands for Ruby. For example, Ruby’s Garbage Collector is now able to collect Symbol type objects. This reduces memory usage of Symbols; because GC was previously unable to collect them before 2.2. Since Rails 5.0 will require Symbol GC, it will support only Ruby 2.2 or later. (See Rails 4.2 release post for details.) Also, a reduced pause time thanks to the new Incremental Garbage Collector will be helpful for running Rails applications. Recent developments mentioned on the Rails blog suggest that Rails 5.0 will take advantage of Incremental GC as well as Symbol GC.
  11. 21.

    Ruby 2.2 includes many new features and improvements for the

    increasingly diverse and expanding demands for Ruby. For example, Ruby’s Garbage Collector is now able to collect Symbol type objects. This reduces memory usage of Symbols; because GC was previously unable to collect them before 2.2. Since Rails 5.0 will require Symbol GC, it will support only Ruby 2.2 or later. (See Rails 4.2 release post for details.) Also, a reduced pause time thanks to the new Incremental Garbage Collector will be helpful for running Rails applications. Recent developments mentioned on the Rails blog suggest that Rails 5.0 will take advantage of Incremental GC as well as Symbol GC.
  12. 22.

    Ruby 2.2 includes many new features and improvements for the

    increasingly diverse and expanding demands for Ruby. For example, Ruby’s Garbage Collector is now able to collect Symbol type objects. This reduces memory usage of Symbols; because GC was previously unable to collect them before 2.2. Since Rails 5.0 will require Symbol GC, it will support only Ruby 2.2 or later. (See Rails 4.2 release post for details.) Also, a reduced pause time thanks to the new Incremental Garbage Collector will be helpful for running Rails applications. Recent developments mentioned on the Rails blog suggest that Rails 5.0 will take advantage of Incremental GC as well as Symbol GC.
  13. 23.

    Ruby 2.2 includes many new features and improvements for the

    increasingly diverse and expanding demands for Ruby. For example, Ruby’s Garbage Collector is now able to collect Symbol type objects. This reduces memory usage of Symbols; because GC was previously unable to collect them before 2.2. Since Rails 5.0 will require Symbol GC, it will support only Ruby 2.2 or later. (See Rails 4.2 release post for details.) Also, a reduced pause time thanks to the new Incremental Garbage Collector will be helpful for running Rails applications. Recent developments mentioned on the Rails blog suggest that Rails 5.0 will take advantage of Incremental GC as well as Symbol GC.
  14. 24.

    Ruby 2.2 includes many new features and improvements for the

    increasingly diverse and expanding demands for Ruby. For example, Ruby’s Garbage Collector is now able to collect Symbol type objects. This reduces memory usage of Symbols; because GC was previously unable to collect them before 2.2. Since Rails 5.0 will require Symbol GC, it will support only Ruby 2.2 or later. (See Rails 4.2 release post for details.) Also, a reduced pause time thanks to the new Incremental Garbage Collector will be helpful for running Rails applications. Recent developments mentioned on the Rails blog suggest that Rails 5.0 will take advantage of Incremental GC as well as Symbol GC.
  15. 25.
  16. 26.
  17. 30.

    Things people are doing with JavaScript • Client-side apps •

    Server-side apps - Node.js (& io.js) • iOS & Android apps (using React Native) • Windows Phone apps • Desktop app (e.g. for Windows & GNOME)
  18. 35.
  19. 36.
  20. 37.
  21. 39.

    Why are we doing this (ClojureScript)? Because Clojure rocks, and

    JavaScript reaches… — Rich Hickey (creator of Clojure)
  22. 42.
  23. 43.
  24. 44.

    Ruby’s advantages • Doesn’t have this • Sane boolean semantics

    • No need for a book called “Ruby: The Good Parts” • No wtfruby.com • Solid core library • Extensive standard library • Do you really need more?
  25. 47.

    • Initial release - 22.01.2010 • Used in production by

    2013 • Popularity spikes in 2014 after the launch of the Volt web framework • Latest version (0.8.0) was released on 16.07.2015
  26. 51.
  27. 59.

    /* Generated by Opal 0.7.0 */ (function(Opal) { Opal.dynamic_require_severity =

    "error"; var self = Opal.top, $scope = Opal, nil = Opal.nil, $breaker = Opal.breaker, $slice = Opal.slice; Opal.add_stubs(['$puts', '$capitalize', '$hello']); Opal.Object.$$proto.$hello = function(name) { var self = this; return self.$puts("Hello, " + (name.$capitalize()) + "!"); }; return self.$hello("bruce"); })(Opal);
  28. 60.

    Opal.Object.$$proto.$hello = function(name) { var self = this; return self.$puts("Hello,

    " + (name.$capitalize()) + "!"); }; return self.$hello("bruce");
  29. 63.

    "/* Generated by Opal 0.7.2 */ \n(function(Opal) {\n Opal.dynamic_require_severity =

    \"error\";\n var self = Opal.top, $scope = Opal, nil = Opal.nil, $breaker = Opal.breaker, $slice = Opal.slice;\n\n Opal.add_stubs(['$puts']);\n return self.$puts(\"Hi, eurucamp!\")\n}) (Opal);\n"
  30. 64.

    /* Generated by Opal 0.7.2 */ (function(Opal) { Opal.dynamic_require_severity =

    "error"; var self = Opal.top, $scope = Opal, nil = Opal.nil, $breaker = Opal.breaker, $slice = Opal.slice; Opal.add_stubs(['$puts']); return self.$puts("Hi, eurucamp!") })(Opal);
  31. 65.

    Ruby to JS mapping • self -> this (mostly) •

    Ruby method/block -> JS function • Ruby string -> JS string • Ruby number -> JS number • Ruby array -> JS array • Ruby hash -> custom JS type
  32. 69.

    `window.title` # => "Opal: Ruby to JavaScript compiler" %x{ console.log("Opal

    version is:"); console.log(#{RUBY_ENGINE_VERSION}); } # => Opal version is: # => 0.8.0
  33. 70.

    require 'native' window = Native(`window`) window[:location][:href] # => “http://opalrb.org/docs/“ window[:location][:href]

    = "http://opalrb.org/" # will bring you to opalrb.org window.alert('Hey campers!')
  34. 73.

    # JavaScript: # ($a = foo) # .bar # .apply($a,

    [1].concat([2, 3])) foo.JS.bar(1, *[2, 3]) foo.JS.bar 1, *[2, 3]
  35. 74.

    # JavaScript: # ($a = (TMP_1 = function(arg){ # var

    self = TMP_1.$$s || this; # if (arg == null) arg = nil; # return "" + (arg.method()) + " " + (self.$baz(3)) # }, # TMP_1.$$s = self, TMP_1), # foo.bar)(1, 2, $a); foo.JS.bar(1, 2) { |arg| arg.JS.method + baz(3) }
  36. 75.

    # JavaScript: foo["bar"] foo.JS[:bar] # JavaScript: foo[2] foo.JS[2] # JavaScript:

    foo["bar"] = 1 foo.JS[:bar] = 1 # JavaScript: foo[2] = "a" foo.JS[2] = :a
  37. 76.

    require 'js' # new foo(bar) JS.new(foo, bar) # delete foo["bar"]

    JS.delete(foo, :bar) # "bar" in foo JS.in(:bar, foo) # foo instanceof bar JS.instanceof(foo, bar) # typeof foo JS.typeof(foo)
  38. 84.

    Very basic corelib No stdlib Semicolons Misc WTFs JavaScript Performance

    Debugging Ruby Compatibility Ruby WTFs Opal File Size
  39. 86.
  40. 88.
  41. 91.
  42. 92.
  43. 94.

    Ruby compatibility • Mostly compatible with Ruby 2.0 • Tested

    against RubySpec • Implements most of the Ruby corelib • Implements some of the stdlib (e.g. Set)
  44. 95.

    Notable differences • true and false are translated to JavaScript’s

    booleans • All numbers are JavaScript floats • Strings are immutable • Symbols are strings • No dynamic requires • No threads • No frozen objects • All methods are public
  45. 98.

    Very basic corelib No stdlib Semicolons Misc WTFs JavaScript Complexity

    Performance Debugging Ruby Compatibility Ruby WTFs Opal Complexity
  46. 99.
  47. 100.
  48. 101.
  49. 102.
  50. 104.

    $document.ready do alert 'yo folks, I'm all loaded up in

    here' end $document.body.style.apply { background color: 'black' color 'white' font family: 'Verdana' } Browser::HTTP.get '/something.json' do on :success do |res| alert res.json.inspect end end
  51. 106.

    Element.find('#header') Element.find('#navigation li:last') Document.ready? do alert 'document is ready to

    go!' end Element.find('#header').on :click do puts 'The header was clicked!' end
  52. 107.
  53. 109.
  54. 120.