00:00:00.030
We have our third and final Tom for the day. This is Tom Gamon, who moved here from the UK two years ago. He switched from working in social media to become a Ruby developer. He works with Disco Labs, which builds custom apps for the Shopify platform. His talk today is about JRuby and his curiosity for all things Ruby.
00:00:07.379
Hello! Just before I get started, I want to mention that I got a bit envious of everyone's really slick presentations. So, I have added a bit more pizzazz to my slides, and I think you’re going to be very impressed. However, I am feeling a bit insecure about it, so if you see something extra flashy, just give me a cheer to build my confidence, okay? Let's get started!
00:00:34.620
What the hell is JRuby? We will explore the adventures beyond MRI. A little bit about me: my name is Tom, as mentioned, and I work for Disco Labs. I have had a recent name change—don’t worry about it. As I recently discovered, I am a noob. This crushing realization hit me while I was trying to run a command to see what versions of Ruby I could install.
00:01:00.899
I came up with an excessive list but understood that it was just different versions of Ruby. However, it left me flummoxed about what all these versions truly meant. So, here's poor old me trying to install some Ruby, and now I don’t even know what Ruby is, leading to a full philosophical and existential crisis. Let's try to tackle this!
00:01:28.890
So, first up, here are the types of Ruby that were returned to me. We have JRuby and MRI Ruby, which we will spend most of our time discussing and comparing the two. Then we have Rubinius and Truffle Ruby, which we will briefly glance at. Lastly, there are M Ruby, Glyph, and Ruby Enterprise Edition; I will give these a one-liner just to understand where they fit into the landscape.
00:02:03.080
The questions I want to answer in this talk are: What is JRuby? How is it different from normal Ruby? What even defines what Ruby is? Does JRuby have the same syntax as normal Ruby? Why would you use JRuby, and are there any downsides? What is Rubinius, and what is Truffle Ruby? And what's the rest of that motley crew? I want this talk to provide you with a conceptual framework to understand JRuby and other Ruby implementations. I understand that for some people, this might be like teaching a grandmother to suck eggs—sorry for the non-native English speakers, but get someone to explain that to you.
00:02:50.420
If we start from the beginning, we can bring everyone on this journey with us. So here we go. Okay, fairly confident. JRuby is the Ruby programming language implemented in Java.
00:03:09.230
What does that mean? Let’s break this down. If we talk about the programming language separately from its implementations, then it must exist independently. So, what does it look like? What defines what Ruby is?
00:03:15.650
Initially, there was basically just one Ruby that Matz invented, and the Ruby language was defined by what the Ruby language could do. So, if you want to know what Ruby is, you look at Ruby itself. It's a bit circular. But as the number of Ruby implementations began to grow, there was a push for a bit more defined standard.
00:03:42.019
There was play with an ISO standard created in 2010, but it was essentially useless to most people; the more interesting one is the Ruby specs. The Ruby specs are essentially a massive test suite that tests all the features of the Ruby language. This is how the language is largely defined today, and how the alternative Rubies check their compatibility to ensure they conform to Ruby's definition.
00:04:05.840
For example, here's a test spec for the 'puts' method. It turns out that the outputs are much more complicated than you think. But essentially, if you call 'puts' with something, it should return nil. If you can get this test suite to pass, you basically have yourself a Ruby implementation.
00:04:27.960
So, Ruby is defined by the Ruby specs. Now, what does it mean for the Ruby programming language, defined by the Ruby specs, to be implemented in Java?
00:04:35.200
This is how it really works: you run your Ruby script, some magic happens, and you get output—like 'Hello, World'. To understand what it means for Ruby to be implemented in Java, we need to look at the process in a bit more detail.
00:05:01.780
In the steps, your lovely Ruby code is tokenized and becomes something the CPU can understand. Because, largely, CPUs don't easily understand Ruby as it's a high-level language. To keep the CPU happy, we need to convert it into machine code to execute those instructions. This process is what defines the Ruby implementation.
00:05:56.229
If you implement Ruby in C, you end up with C Ruby or MRI—the standard Ruby that we all know and love. What about JRuby, which is implemented in Java? Essentially, all this means is that the part that handles converting Ruby into machine code is written in Java rather than Ruby.
00:06:20.919
Instead of receiving our YARV instructions, we end up with Java bytecode. This Java bytecode runs on the Java Virtual Machine (JVM). That’s essentially JRuby: the Ruby programming language implemented in Java. However, this may feel a bit unsatisfying. Understanding what something is, isn’t all that useful.
00:06:59.139
So let's dig deeper and compare JRuby with MRI Ruby, and explore why you might choose JRuby over standard Ruby.
00:07:05.100
Does JRuby have the same syntax as normal Ruby? Yes, it does! It's not like crystal or elixir, which are similar but not quite Ruby. It's worth noting that most alternative Ruby implementations generally provide a subset of the language.
00:07:12.290
JRuby is fairly well-featured and supports up to Ruby 2.5, while we are now on 2.6 and beyond. Most alternative implementations will do some subset of the language but may differ more or less depending on the implementation. It's important to note that you can run Rails in JRuby, which is exciting!
00:07:25.680
Now, why would you choose JRuby over MRI? While researching this, I found that Java was originally developed by James Gosling, which was amusing, but that’s beside the point. This essentially leads us to why you would run JRuby: speed. Charles Nutter, the lead dev from JRuby, lent me some slides comparing the performance of a Rails app processing requests.
00:08:04.400
The benchmark shows that more requests per second is better, which means JRuby is indeed quicker. However, just like any benchmark, your mileage may vary. But let's assume it's quicker, mainly due to the JVM.
00:08:27.100
The JVM is the culmination of decades of research and development that has solved many complex computer science problems, such as garbage collection and just-in-time compilation. Because of these enhancements, JRuby can be significantly faster.
00:09:02.790
Additionally, JRuby offers portability: the Java philosophy of Write Once, Run Anywhere allows Ruby to run where it couldn’t before. JRuby also boasts great driver compatibility. Just as with C Ruby, you can run C libraries with JRuby, but also Java libraries, which is powerful.
00:09:26.410
JRuby has great tools available, allowing for performance profiling and memory management. I'm going to link you to a talk by Charles Nutter and other developers that delves into that topic much deeper. One thing often discussed in alternative Ruby implementations is threading.
00:10:03.480
You hear a lot about multi-threading, native threads, green threads, and the like. So let’s quickly cover processes, threading, concurrency, and parallelism.
00:10:46.080
Think of a process as a development agency. When you start a Ruby script, it starts a new process, which has one thread. That thread represents a developer within the agency. Just like a developer can perform work by sharing resources, Ruby, by default, has one main thread that executes its tasks.
00:11:10.930
This leads to a serial execution model. Let’s say a developer is working on multiple features sequentially. If both features each take a significant amount of time, the whole thing takes longer than necessary.
00:11:37.490
The issue lies with long-running tasks, such as test suites that must finish before moving on to the next task. This leads to wastefulness in time.
00:12:13.890
The common misconception is to add more threads to speed up the execution process. This would typically create an environment where you could develop code more quickly. But with MRI Ruby, we have the global interpreter lock (GIL). The GIL is a feature of Ruby that permits only one thread to execute code at a time.
00:12:48.500
Think of it like an overly cautious agency owner worried about developers overwriting each others’ code. To mitigate this, they limit power sources, resulting in limited productivity. With the GIL in MRI Ruby, only one developer can work simultaneously.
00:13:31.600
Under this concurrency model, developers might work on their test suites in parallel rather than waiting for one complete task to finish before starting another, leading to a more efficient workflow.
00:14:05.620
However, concurrent execution still introduces complexities and worries about potential issues when managing multiple threads. Working with multiple threads could lead to developers inadvertently overwriting each other's code.
00:14:49.610
With JRuby, they bypass the global interpreter lock, allowing for true parallel execution. This means two developers can work simultaneously, increasing productivity. This ability contributes to why JRuby can provide excellent performance, along with the various alternative Ruby implementations.
00:15:49.380
But are there any downsides? It tends to have a longer warm-up time and slower startup initially. The graphs indicate that JRuby starts a bit slower but gains performance as it runs. It can also be more memory-intensive than MRI Ruby.
00:16:06.070
While you lose direct compatibility with C libraries with JRuby, many popular libraries have been ported for use in JRuby, such as Nokogiri.
00:16:42.840
Also, since JRuby is a subset of the Ruby language, it lacks some newer features you might find in MRI Ruby.
00:17:26.180
Now, let's cover Rubinius, Truffle Ruby, and the rest of that motley crew. Rubinius confusingly implements Ruby in Ruby itself—with its core libraries written in Ruby. It provides features like multi-threading without a global interpreter lock, allowing better performance.
00:17:57.400
Truffle Ruby, on the other hand, runs on the JVM, like JRuby, but employs a unique just-in-time compiler called Graal, allowing the execution of various programming languages, including Ruby.
00:18:30.420
Maglev and Ruby Enterprise Edition were once notable, but both are largely abandoned now. M Ruby offers a more lightweight version for embedded systems.
00:18:45.130
In conclusion, there are various Ruby implementations, all being the Ruby programming language implemented in different ways. If any language can pass the Ruby specs, it is regarded as Ruby. JRuby, specifically, is the Ruby programming language implemented in Java.
00:19:21.570
You may opt for JRuby primarily for its performance benefits. Thank you for listening! I’ve got some references for further reading, including books like 'Working with Ruby Threads' and 'Ruby Under a Microscope,' which are excellent resources. I also borrowed a few slides from this talk that you can access online. Finally, I would love to share my side project, which focuses on amplifying the voices of incredible women in various fields. If you know someone who deserves recognition for their achievements, please visit thisisartemis.com and use the nomination form.