Talks

Evaluate Ruby Without Ruby

Evaluate Ruby Without Ruby

by Takashi Kokubun

In the talk "Evaluate Ruby Without Ruby" at RubyConf 2016, speaker Takashi Kokubun introduces the concept of using mruby, a lightweight implementation of Ruby, to evaluate Ruby DSL (Domain-Specific Language) configurations without relying on traditional Ruby interpreters like MRI. Takashi, a developer at Cookpad, shares insights on how to build a tool that allows the execution of Ruby scripts within a broader application ecosystem that is not inherently Ruby-based.

Key Points Discussed:
- Introduction to DSL: The session starts with an overview of Ruby DSL, highlighting its application in simplifying configurations for software packages like ngx, which can operate across different Linux distributions. It emphasizes the clarity offered by DSL compared to JSON for configuration tasks.

  • Issues with MRI Dependency: Takashi explains the motivations for seeking alternatives to MRI for DSL evaluation, emphasizing complications in bootstrapping development environments. Many Linux distributions do not come with MRI pre-installed, making initial setup cumbersome. The talk outlines how dependencies on MRI can increase complexity, especially regarding gem setups.

  • The Role of mruby: To solve these issues, the speaker presents mruby as a viable solution. By embedding mruby, developers can create small executable binaries that avoid the pitfalls of managing multiple Ruby versions and dependencies, simplifying the setup process.

  • Implementation with mruby: The implementation process involves obtaining the mruby repository, compiling it, and integrating it into existing software using the mruby C API. This allows Ruby scripts to be executed from non-Ruby apps, providing a versatile way to include Ruby DSL in various contexts.

  • Configuring a Portable CRI App: Takashi discusses two methods to implement applications with Ruby DSL using mruby: 1) Leveraging mruby in conjunction with Go to produce a single binary capable of executing integrated Ruby scripts. 2) Using mruby alone for both DSL and core functionalities, reinforcing the language interoperability.

  • Handling Command Outputs: The speaker also mentions the use of the open3 library for capturing outputs from executed commands, demonstrating how to streamline environment management effectively.

Conclusions and Takeaways:
- The primary goal discussed in this talk is to simplify development environment setups through a Ruby DSL that reduces reliance on MRI, making the process more accessible and efficient. Takashi emphasizes the role of mruby in bridging Ruby scripts with a broader application landscape, thereby enhancing productivity and reducing maintenance costs.

- The talk concludes with an invitation for audience questions, fostering engagement around these technical solutions.

00:00:15.209 Let's start talking about evaluating Ruby without Ruby. My name is Takashi Kokubun, and I work at Cookpad, which is a company in Japan that hosts a recipe-sharing service. I'm working as a developer in the productivity group at Cookpad, and we provide different environments for these applications.
00:00:23.320 Today's topic is Ruby DSL. I implemented a tool using mruby, and I will show you the reasons behind my implementation. This talk will also serve as an introduction to mruby and discuss two ways to build portable CRI applications configured by the DSL. First, let's discuss the concept of DSL. A Domain-Specific Language (DSL) is a programming language specialized to a particular application domain. Ruby DSL is a DSL defined in terms of the Ruby language.
00:01:12.429 For example, I'm talking about a Ruby DSL today, specifically regarding the package ngx, which can work on both CentOS and Ubuntu. The next section will cover service injections, which enable the injection of startup processes to massive servers. As you can see, installing the ngx package and setting up service injections are abstracted away for certain distributions, allowing us to configure these processes with Ruby. Writing configurations in JSON can be tedious, so we prefer using DSL for clarity and ease.
00:01:56.530 How is the DSL implemented? Have you ever implemented a DSL? For example, if you want to evaluate the package `nginx`, a simple implementation defines a DSL class with a package method. When the package method is called, it stores the package name to a result variable, which can be retrieved from the DSL's result method. For more complex cases, if the package has nested DSLs, like an action, we need to specify the action. To implement this, you have to create a package class, and you can evaluate nested actions within it using instance methods.
00:03:03.420 Usually, Ruby DSL is implemented with MRI, using instance_eval or instance_exec. However, we want to evaluate Ruby DSL without MRI. Why is that? Let's look at our motivation. Ruby DSL is used in several contexts, and we have developed a development environment bootstrap script for macOS and Windows. We aim to utilize Ruby DSL to simplify and describe operations across multiple OS distributions, reducing maintenance costs.
00:04:24.930 Thus, we are working with a configuration management tool we call ‘Utama’, which means 'the main chef.' The inspiration for ‘Utama’ was derived from the Chef provisioning tool. For instance, if you write DSL for installation of `memcached` and `PostgreSQL`, you can manage installation across different distributions seamlessly. However, bootstrapping development environments using MRI has its challenges, specifically regarding the difficulties of using MRI and maintaining Ruby versions across platforms like macOS and various Linux distributions.
00:05:33.479 Most Linux distributions don’t ship MRI out of the box, and we prefer not to manually install MRI before bootstrapping. This is primarily because it complicates the first steps of setting up a developer environment. If you depend on MRI, you also have to manage gem setups every time you run the DSL for bootstrapping. Thus, our goal is to eliminate the dependency on MRI to resolve these issues.
00:07:00.700 How can we embed Ruby VM into our software? To tackle this, I will discuss mruby, which is a lightweight implementation of Ruby that is available in both hardware and software. By embedding mruby into our software, we can compile Ruby scripts into very small binaries, allowing execution even on limited-resource hardware.
00:08:04.330 When you use mruby, you can evaluate Ruby scripts within any software, even if the software is not written in Ruby. This capability allows us to build a tool that evaluates the DSL independently of MRI, unlike traditional implementations that require MRI.
00:09:06.490 To use mruby, you need to obtain the mruby repository and run a make command. This process results in an executable binary that can be linked to your software. You then use the mruby C API or language bindings to integrate with it. This enables the execution of Ruby scripts from your software, and you can capture the output as C strings. Thus, embedding mruby empowers us to circumvent the dependencies related to MRI.
00:10:38.330 Looking at the implementation of a portable CRI app configured by DSL, there are two methods available. One option is to use mruby to manage the Ruby DSL implementation while using Go for the rest of the application. This method allows you to compile the Go scripts into single binaries, facilitating the use of Ruby scripts integrated into that binary.
00:12:07.970 The second method, which was introduced today, provides a way to implement both Ruby DSL and other functionalities using mruby. For both implementations, it is essential to create efficient methods for initializing and evaluating the DSL. This allows us to achieve the desired effect without the complexities of maintaining multiple language bridges.
00:13:07.510 Using mruby, we implemented essential components in Ruby while supporting the ability to use C for underlying operations. This illustrates how interoperability between Ruby and other languages can streamline processes and configuration management.
00:14:33.090 Additionally, we can create tools that effectively capture outputs, including standard output and errors from commands executed in the environment. Over time, we have developed several methods within the open3 library to handle these operations while using Ruby, which can also leverage the functionality provided by mruby.
00:16:24.180 The primary takeaway from this talk revolves around simplifying the setup of a development environment using a DSL that configures a single binary application through mruby. This approach helps eliminate dependency on MRI while allowing for the seamless integration of Ruby DSL into the broader development ecosystem.
00:22:10.480 Thank you for your attention, and I welcome any questions regarding the topics we've covered today.