Talks

Opal.rb

wroc_love.rb 2016

00:00:11.540 Hi everyone! I'm really pleased to be here in Poland, and I will start by quoting Angel, who just said, "You won't go and do microservices with JavaScript." Let's talk about that. Maybe it's not that crazy. Maybe you won't go writing it in JavaScript, but who knows?
00:00:24.130 This is a quotation from Mats, and it’s very true and very interesting. But in 2016, this is what we face. I don't think anyone here is going to decide between Assembly and something else, but most of us, I think, as children, had to do some JavaScript. So, let me introduce you to Joe, the average developer from the stock images of 'Mabel.' Joe has done some Rails, can use Capistrano, practice Test-Driven Development (TDD), and knows about jQuery.
00:00:55.970 He knows about HTML, CSS, and how many people face it? They are kind of like this guy. Okay, so this is Joe.
00:01:18.730 But the reality is that he has to do some JavaScript. I think most of us are web developers, right? Is there anyone here who is not a web developer? Nice, one hand! Okay, so we all have to deal with some JavaScript. We often offload the JavaScript to some front-end developer. We try to survive with JavaScript, and the reason is probably that we come from Ruby. I think we all come from Ruby.
00:01:43.989 What have you noticed when you compare JavaScript to Ruby? You know that if you instantiate a new Boolean, passing in 'true' and try to compare it with 'true,' the values can be different. There are all kinds of nuances in JavaScript, which, by the way, is a nice language. Quoting Mats again, it's just a bit more primitive than our beloved Ruby.
00:02:11.890 Probably the major problem is that it lacks a really good core library. So, I want to invite you to take a fresh look at JavaScript. This is very true because we are all used to writing applications with the metaprogramming of Active Record, callbacks, and all that stuff. Maybe we are not bored by Ruby, but we are used to it, and it presents a challenge.
00:02:43.930 I invite you to try Opal. If anything, because it's fresh, it's funny, and I don't know how many of you have ever tried UI with RubyQT or the OTC SDK? No one? Oh wow, good! I've done that too, and well, it's different. It's very different.
00:03:21.510 You encounter different challenges, such as programming with threads in Ruby—something almost no one does. By the way, I recommend that too, because if you want to have some fun, you can do cool stuff with that.
00:03:54.400 So, Opal is a Ruby to JavaScript source-to-source compiler. This means that we don't have a virtual machine or some complicated Assembly compiler. Instead, we translate concepts from Ruby to JavaScript. For example, a method in Ruby corresponds to a function in JavaScript, a class in Ruby is a prototype chain in JavaScript, and an array in Ruby will be an array in JavaScript.
00:04:44.860 This allows us to be fast because we don't have any issues with performance, yet we retain the great features of Ruby. For example, methods are distinct from instance variables. As for some numbers about Opal, we have around 3K stars, which I am proud of. We’ve passed 10K; actually, it's 11 recently, of Ruby spec examples.
00:05:52.240 If you don't know about the Ruby spec project, it started with Ruby news to test the Ruby language and to ensure Ruby implementations behave just like Ruby. The original Ruby tests are not that precise; they are more like smoke tests. They're good for what they do, but this was necessary for Ruby news.
00:06:29.150 Over time, it became a good thing for other implementations as well; JRuby uses it, and I believe that a lot of Ruby implementations rely on this.
00:06:58.579 With Opal, we have method missing with blocks, we have required and download with classes, singleton classes, modules, mixins, and a good chunk of the standard library. We also bridge a number of classes, such as Arrays, Strings, Regular Expressions, Functions, and Booleans.
00:07:32.349 This happens because when you use Opal, the class hierarchy is a prototype chain. Instance variables are just properties, and constant lookups are done through the prototype chain.
00:08:00.140 This is important because all the optimizations and features done in JavaScript by the browsers and vendors will improve performance significantly. However, there are a small number of caveats. I might add that probably the first issue will not be with Opal but will arise from the differences with Ruby 3, as our strings are JavaScript strings.
00:08:50.850 Since JavaScript strings are mutable, you can modify them, which contrasts with Ruby's frozen string literal feature that was introduced in Ruby 2.3. By using that magic comment, you can tell Ruby to freeze all strings in a file by default.
00:09:36.450 Another notable difference is that in JavaScript, numbers are all floats. Since we map numbers to JavaScript numbers, all numbers in Opal are floats too. Of course, we miss some capabilities that can be performed in a browser, like threading or opening files, but you can do some of that stuff with Node.
00:10:03.140 I still don’t know of anyone who has implemented microservices in Node using Opal, but you can do it if you want.
00:10:38.100 Opal is production-ready. I have been deploying it since 2012 in production. The site was big enough that I can claim that millions of users have used it. We have maintained the same codebase for both mobile and desktop applications without any issues.
00:11:12.450 As you can see, it used to be smaller, around 30K, and now it's bigger because we are implementing more and more features from Ruby itself.
00:11:35.640 However, the average image in your site is still significantly larger than that. So, this presentation is basically divided into two parts.
00:11:56.490 The first part I have just finished, and then I want to show you some stuff to give you a feel of how neat it is to program with Opal and how fun it is. One thing I want to add is that if you are interested in deepening your understanding of Ruby or JavaScript, this is a wonderful way.
00:12:26.210 There is a bunch of issues open, as you can imagine, on the Opal repository, more or less difficult. You basically have tasks that are already there, so you will find failing specs that you must implement to make them pass.
00:12:56.830 There are at least two or three contributors who use the project as a kata or exercise, so you will get examples that are not passing, and you need to implement the solutions.
00:13:15.490 But before the demo, let's do a quick crash course on how to use it more practically. The command line interface is more or less like the Ruby one.
00:13:51.500 So, you have a dash to pass inline evaluation, and you can add dash C to compile to JavaScript. Then you can run it just as you would typically in Ruby.
00:14:14.460 You have dash R to require files, and that's up for Kaiser, which stands for runner. You can run stuff in a server and open it in the browser.
00:14:29.720 This is a really great way to debug code. I think if there were something like this for Ruby, it would be a lot different. It's like an IDE for your program.
00:14:43.380 You do have a wrapper for jQuery, which is useful for simple operations. You can select the body and manipulate it, and we also have an Opal browser.
00:15:02.650 This is somewhat similar to how you use the browser in JavaScript. The person who implemented it has gone through the whole Mozilla Developer Network and transcribed all the documentation.
00:15:31.620 You can do the same things you can do with jQuery, but in a more Ruby-like way. Now, let's run some code.
00:16:05.010 We will open up some implementations; I won’t be implementing the full page with an engine or something like that. I already have one prepared that I created the other day.
00:16:25.090 So, if it’s buggy, it's my fault: be patient. Okay, let’s see what we have.
00:16:39.740 We have this page, which looks quite ordinary. I have a first implementation that runs in the console.
00:16:56.900 It’s really simple. You just use the arrow keys or letters to move the items.
00:17:08.370 You’ll need to track a key and then press Enter to move to the new state. Let’s see it in action.
00:17:38.030 If I do nothing, the piece comes down. Okay, it works. Let’s try to make it game over.
00:17:56.960 I’m not very good, but I think this is already funny. Now, let’s try to modify this for the browser. Let's see how that works.
00:18:12.950 I have three implementations in three different ways for Opal; we'll try to do it live, but we can always fall back to the already prepared implementations.
00:18:28.170 We require the necessary libraries, like potato and some scoring pieces for the game.
00:18:51.530 We also have a color map and the grid printer, which takes an array of arrays and allows us to manipulate outputs.
00:19:08.290 As you can see, if the cell is a string or symbol which represents a color, we get a new color from the list.
00:19:50.820 We make a note of it, taking into account that emojis will take two spaces. This establishes the grid.
00:20:35.850 After this, we instantiate the game and start the main loop. The loop will progress the game, letting the figure move down, and we will print everything using the lambdas we prepared.
00:21:24.567 When the game is over, we will alert the user. And there you have it. It's quite simple, as you can see.
00:22:08.190 Next, let’s enable the jQuery functionality. We already have a configuration for Rock that includes all the necessary components.
00:24:12.950 Now, we add the relevant scripts to our HTML to include the required libraries and start building a table in grid-like style. We place our game objects inside the cells of the table.
00:24:57.170 This looks good so far.
00:25:03.960 At this point, things might seem tedious to watch. Please let me know if you find my typos and mistakes boring, and we can switch to looking at the already prepared implementation.
00:26:04.672 Let's continue with building it. We have our table.
00:26:39.200 Now we need to select the right cell, which requires a few more lines of code.
00:27:20.430 We need to capture the keyboard events to move the pieces correctly, which is what makes the game dynamic.
00:28:06.210 One good thing is that we can jump to JavaScript easily for certain functionalities in Opal, all while keeping the syntax Ruby-like.
00:28:45.470 We will set an interval to advance the game every half a second. Let's see if it works.
00:29:23.920 Now, we encountered a runtime error. Let’s debug what went wrong.
00:30:14.070 We can inspect frozen objects to see what's going on. It's critical to trace back the lines of the instance variables.
00:30:57.340 After debugging and fixing the issues, we should now be able to see the shapes progressing and the game rendering correctly.
00:31:37.589 This will include all necessary functionality to control the pieces and win the game smoothly.
00:32:44.890 As we finish our set up, let’s review the documentation to ensure everything works as intended.
00:33:21.970 Now, we can go through the code and understand how we can integrate with HTML to manage more complex interactions.
00:34:00.390 I think we'll take a brief look at some alternative implementations, including a simple HTML DSL, and check for enhancements and optimizations.
00:35:01.189 In the end, these methods offer practical tools for those who want to expand their projects and improve their approach to browser-based applications with Opal.
00:35:45.040 Thank you for attending this talk. I am open to any questions or criticisms as we wrap up.
00:36:13.720 I hope you all enjoyed the session!