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.