DEV Community

Cover image for Ruby Debugging, VS Code, Gems, and Bundler!
Luigi Antonio Guillen
Luigi Antonio Guillen

Posted on

Ruby Debugging, VS Code, Gems, and Bundler!

After installing your Ruby development environment, you might find yourself in the void thinking what to do next. In this article, we take a look at the bigger picture before you, as a developer, would dive into the smaller chunks of going through your projects: setting up your code editor and get to know how gems work, as they are the essentials!

While the article's title may sound like a random mashup of four concepts, it's more like setting up your ground for your code to be written down to running/debugging, knowing how to extend your code through libraries or gems, and make your project immune to dependency hell with the help of Bundler, especially when sharing your projects to everyone else who definitely has a different set of gems installed on their environment!

Debugging

With a fresh installation of your environment, you can immediately run your Ruby file (ending in .rb) in the Terminal. The same is true for Python and various C/C++ compilers (clang, gcc, MinGW)



ruby FILE
# EXAMPLE
ruby /Users/User/Desktop/hello.rb


Enter fullscreen mode Exit fullscreen mode

You can learn more about how your file will be interpreted (flags) by executing ruby -h.

Ruby and Visual Studio Code

For developers who want to streamline their code editor experience into a near-IDE one, code editors like Visual Studio Code (VS Code) offer extensions to streamline your Ruby experience and your development environment!

Extensions

For beginners, I suggest three extensions for you to get started with:

The Ruby LSP and Code Runner works out of the box but the VSCode rdbg Ruby Debugger extension needs configuration after installation. On the next section, we focus on the big elephant in the room, the rdbg Ruby Debugger.

Configuring VSCode rdbg Ruby Debugger

Prerequisites: debug

What makes the rdbg Ruby Debugger distinct from our Code Runner extension is that it makes use of VS Code's debugging part of it, allowing you to make breakpoints and keep track of Variables, Watch, and your Call Stack found in the same Run and Debug view on your sidebar. It is identical to when you try to debug a C/C++ or Python program given you have these VS Code extensions and compilers installed.

After installing the extension, install the debug gem via the terminal



gem install debug


Enter fullscreen mode Exit fullscreen mode

For your launch configurations which are applied only to the scope of your current project, these are the default configurations in your launch.json:



{
        // Use IntelliSense to learn about possible attributes.
        // Hover to view descriptions of existing attributes.
        // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
        "version": "0.2.0",
        "configurations": [
                {
                        "type": "rdbg",
                        "name": "Debug current file with rdbg",
                        "request": "launch",
                        "script": "${file}",
                        "args": [],
                        "askParameters": true
                },
                {
                        "type": "rdbg",
                        "name": "Attach with rdbg",
                        "request": "attach"
                }
        ]
}


Enter fullscreen mode Exit fullscreen mode

If your Ruby project doesn't have launch configurations or you are unsure of it, you can navigate to the Run and Debug in VS Code found on your sidebar. The same action can also be done by navigating to Run > Add Configuration… in the menu bar. This will allow you to configure a launch.json for your currently opened project.
Screenshots of VS Code showing how to add a launch configurationAttempting to debug your program under Run > Start Debugging will pop up a notification on the bottom right that it cannot find a program to debug. Closing the notification will also trigger the same action of configuring your launch.json.
Screenshots of VS Code about attempting to debug a Ruby program without setting up launch.json
You should be greeted with the said JSON file in a new tab.
A screenshot of VS Code showing a launch.json file of rdbg Ruby debuggerFor this purpose, we can save and leave anything unchanged in this file that has been automatically generated for us. For more advanced projects, you might have to tinker on how your project will be debugged with flags (similar to how I discussed earlier on executing ruby -h at the Terminal to learn more about the various flags that can be executed with your project).

Afterwards, you can now debug your code by going to Run > Start Debugging or by hitting F5 on your keyboard. You will be presented with this bundle command for every time you will debug, so simply hit ENTER.

A VS Code screenshot showing a bundle command upon debugging with rdbg Ruby Debugger

A VS Code screenshot on debugging a Ruby program

And voilà! You can now debug your current project, even breakpoints! This is how you'll configure your launch configurations for every new project you'll make on moving forward.

Ruby LSP and Code Runner

Since they run right away after installing these extensions, I'll give you a quick run through of these extensions!

First is the Ruby Language Server Protocol (LSP), this extension is similar with the C/C++ and Python extensions in VS Code in that it can display documentation and suggestions of certain keywords as you type them in.
Screenshot of VS Code showing a documentation of a Ruby keyword with the Ruby LSP extension installed

And second is Code Runner. It also works for a variety of other programming languages as it simply taps in to the Terminal to execute your Ruby project.
A screenshot of VS Code showing a Ruby program being run using Code Runner

Now that VS Code is seamless with how you manage, run, and debug your Ruby projects—and speaking of projects—let's tackle about gems!

💎📚 Gems

Like I shared in my first Ruby article, gems are libraries of Ruby code that can be reused and for the simplicity sake of your code (especially if you can think that such a function may be already open-sourced by others). For context, gems are analogous to C/C++ library (.h) files.

RubyGems is the Ruby's community hub for these gems while also serving itself as a gem hosting service. Not only you can install but also publish your own gems that you may think others may find it helpful! Treat this as your directory plus documentation for gems that you might search in the future!

Installing Gems

Installing a gem to your Ruby environment involves this command syntax:



gem install [NAME]


Enter fullscreen mode Exit fullscreen mode

Some gems in their documentations may require you to run this command with a sudo command such as the rails gem for example.

For users that use a version manager to manage their Ruby environments (i.e. rbenv, rvm, or asdf), installing a gem in one version may be independent from another version; it will not carry across different Ruby versions.

By default, your Ruby development environment comes with essential gems necessary for building on top of other gems. For a fun little exercise, we can make use of a gem in a sample project that is more down-to-earth!

Using Gems in Your Ruby Project

To include a gem to use in your project, the syntax is as follows,



require '[NAME]'


Enter fullscreen mode Exit fullscreen mode

In our sample project, let's make use of the matrix gem that's included with our Ruby installation. If it comes that you run this sample code and stopped with an error because this gem is not found, you can execute gem install matrix in the Terminal.



require 'matrix'


Enter fullscreen mode Exit fullscreen mode

Now let's define a matrix and print the determinant of this! Take note of Ruby's object-oriented nature, as that's how you "call" things from a class on libraries (as seen in mat.determinant).



require 'matrix'
mat = Matrix[[2, 3], [5, 6]]
puts mat.determinant # => -3


Enter fullscreen mode Exit fullscreen mode

And that's how you can use gems in your Ruby project! If you want to learn more about the documentation of the matrix gem, you can head here!

For an index of the documentations of gems, you can head to rubydoc.info or ruby-doc.org!

🔨 Bundler

Prerequisites: bundle

When sharing Ruby projects with the gems you used to someone else (such as GitHub), it is likely that they can't run it because they haven't installed it on their own environments or they have the gems but somehow, a newer or older version is interfering with the gems they have on their environment, this is what I meant by dependency hell.

Bundler eliminates that, as its job is to keep an exact list of gems and optionally specify versions of gems for your project. This ensures that other people will have these exact gems installed without them manually telling them about it with a simple command later on.

Upon installing Ruby, the bundle gem should come with the installation. If somehow this gem doesn't exist, you can install it with the gem command.

Getting Your Project Ready for Bundler

In your project folder, Bundler needs two files, Gemfile and Gemfile.lock (yes, the first file doesn't have an extension). You can add a file by the Explorer found in the sidebar in VS Code:
Screenshot of VS Code adding a new file via the ExplorerIn addition, you can do the same action using the touch command in Unix/Unix-like systems (i.e. Linux and macOS) in the terminal.



touch Gemfile Gemfile.lock


Enter fullscreen mode Exit fullscreen mode

Now, let's focus on the Gemfile!

The Gemfile

The Gemfile is where you can specify the gems that will be used by your project. This file will be read by Bundler.

In practice, you include the source of where your gems should be downloaded from, though this is not required at all times. In this case, RubyGems will be our source since they also host gems!



source 'https://rubygems.org'


Enter fullscreen mode Exit fullscreen mode

Listing a gem in the Gemfile is done through this similar syntax, differing only by a word when we require a gem in our project:



gem '[NAME]'


Enter fullscreen mode Exit fullscreen mode

In another sample project, let's try to include another gem that's not installed in our fresh Ruby environment, the fibobacci gem!



source 'https://rubygems.org'
gem 'fibonacci'


Enter fullscreen mode Exit fullscreen mode

With this gem syntax, by default it will install the most current release of that gem. Should you need to install a gem with a specific version is in the form of this syntax, using fibonacci as an example:



gem 'fibonacci', '~> 0.1.8'


Enter fullscreen mode Exit fullscreen mode

After listing the gems you need for your project, simply run this command in VS Code's terminal:



bundle


Enter fullscreen mode Exit fullscreen mode

When you make changes to your Gemfile, you can run this command again. Additionally, you can view the information of that gem you installed and where it's at by executing bundle info [NAME].
A VS Code screenshot showing a Gemfile document open and a Terminal installing gems using BundlerNow we can get the first n terms of a Fibonacci sequence where n is inputted by the user with this snippet of code!



require 'fibonacci'

fib = Fibonacci.new
num = gets.chomp.to_i # Removes the terminating character at the end of the input and converts the input to integer
fib.print(num)


Enter fullscreen mode Exit fullscreen mode

You can learn more about getting started with Bundler here! If you want specifics about how the Gemfile works, then head here!

Conclusion

Now that you have a near-IDE experience with VS Code, learned more about how to embed gems in your project, and learned the basics of Bundler so that other developers can also tap in to your project with the exact gems that you used, you can definitely rest easy and code away on your Ruby journey!

Most of what I shared here, particularly with gems and Bundler, is just the foundation of what you'll encounter later with other gems and frameworks in Ruby!

That is all, I hope you learned a lot about Ruby with this one! :)

Top comments (0)