Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Opal: The Journey from JavaScript to Ruby

Opal: The Journey from JavaScript to Ruby

Slide-deck from my presentation at RubyConf Kenya 2017.

Bozhidar Batsov

June 11, 2017
Tweet

More Decks by Bozhidar Batsov

Other Decks in Programming

Transcript

  1. Bug

  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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.
  8. 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)
  9. Why are we doing this (ClojureScript)? Because Clojure rocks, and

    JavaScript reaches… — Rich Hickey (creator of Clojure)
  10. 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?
  11. • 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
  12. /* 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);
  13. Opal.Object.$$proto.$hello = function(name) { var self = this; return self.$puts("Hello,

    " + (name.$capitalize()) + "!"); }; return self.$hello("bruce");
  14. "/* 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"
  15. /* 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);
  16. 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
  17. `window.title` # => "Opal: Ruby to JavaScript compiler" %x{ console.log("Opal

    version is:"); console.log(#{RUBY_ENGINE_VERSION}); } # => Opal version is: # => 0.8.0
  18. 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!')
  19. # JavaScript: # ($a = foo) # .bar # .apply($a,

    [1].concat([2, 3])) foo.JS.bar(1, *[2, 3]) foo.JS.bar 1, *[2, 3]
  20. # 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) }
  21. # 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
  22. 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)
  23. Very basic corelib No stdlib Semicolons Misc WTFs JavaScript Performance

    Debugging Ruby Compatibility Ruby WTFs Opal File Size
  24. 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)
  25. 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
  26. Very basic corelib No stdlib Semicolons Misc WTFs JavaScript Complexity

    Performance Debugging Ruby Compatibility Ruby WTFs Opal Complexity
  27. $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
  28. 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