Talks

The joy of Ruby debugging - Pry universe

The joy of Ruby debugging - Pry universe

by Enrico Carlesso

In this talk titled "The Joy of Ruby Debugging" presented by Enrico Carlesso at RubyDay 2015, the focus is on efficient debugging practices in Ruby using the Pry tool. The speaker, a software developer with a decade of experience, shares insights into how debugging can significantly affect a developer's productivity and the ins and outs of using Pry to streamline the debugging process.

Key Points Discussed:

- Introduction to Pry: Pry is introduced as an advanced alternative to the default Interactive Ruby Shell (IRB), providing features such as syntax highlighting, tab completion, and access to object documentation, which enhances the debugging experience.

- Debunking Traditional Debugging Methods: Carlesso discusses the traditional debugging approach, emphasizing how developers often spend disproportionate amounts of time understanding and fixing code rather than writing it.

- Features of Pry: The audience learns about significant features of Pry, including:

- binding.pry: A command that allows pausing code execution and accessing the context to inspect variables.

- cd and ls commands: Which facilitate navigation through object methods and current local variables, respectively.

- Edit command: Enables opening the specified method or class in an external editor directly from Pry.

- Plugins such as pry-remote and pry-byebug: These enhance debugging capabilities, allowing remote connections to a REPL and better stack navigation.

- Real-life Debugging Example: Carlesso demonstrates the features of Pry using a live coding session, specifically showcasing the Tower of Hanoi problem. Throughout the process, he highlights how using binding.pry at various points allows for real-time inspection of code execution and state management in debugging.

- Streamlining with Pry-Rescue: A new feature is introduced that automatically opens the Pry console upon encountering exceptions, saving time when errors arise.

- Customization of Pry: The speaker encourages developers to leverage Pry's flexibility by creating custom commands and extending its functionalities to better suit their workflow.

Concluding Takeaways:

Enrico Carlesso concludes that using Pry can dramatically enhance the debugging workflow in Ruby applications. He emphasizes the importance of quickly accessing real-time data during debugging sessions, leveraging the extensive features Pry offers, and encourages the audience to not hesitate in inspecting and modifying code, even in libraries. Carlesso hopes that attendees will integrate Pry into their development processes to improve efficiency and joy in debugging.

00:00:10.160 Hi everybody, thank you for your warm welcome. I would like to thank all the organizers of this day. They have done a great job, and it is truly a pleasure and an honor to be here. So, thank you for all the time you have spent on this event. My name is Enrico Carlesso, and I have been a software developer for the past 10 years. I must admit that I am not an experienced speaker, so I apologize in advance for that.
00:00:33.879 You might ask why I am giving this talk. When I found out it was Ruby Day, I reflected on what has really changed my life when it comes to working in Ruby. Even though I don't particularly enjoy speaking in public, I would like to share with you the tool that has dramatically changed the way I work and has saved me a significant amount of time.
00:01:07.200 Just a brief mention about the company I work for, named Codor 51, which is based in Bologna. I've been working with them for the past two years. Unfortunately, our journey together has come to an end, but it has been a great pleasure to work with you all.
00:01:48.520 The topic of debugging is quite interesting, especially since this talk follows one from Kristoff, as our discussions share a lot of common ground. As Kristoff mentioned, we often spend much more time reading code than writing it. This is primarily because we are continuously debugging our code. You write something, unsure if it will work. You might be working on someone else's code, and in those cases, you often don't know what you're doing. This makes the process of reading and understanding your code a lengthy one.
00:02:16.440 Typically, the debugging process goes like this: you need to find an exception and hope you have the stack trace. If you don't know how to use the trace course gem from Kristoff, you might end up relying solely on the stack trace. You open your editor, search for the relevant line, start adding some puts statements to check values, and then try running the code again. For many languages that are not scripted, this process often involves seeing thousands of outputs. With Ruby, however, you usually don't need to compile; instead, you just check the output and make some changes, hoping for a positive result.
00:02:46.000 If you are very lucky, you might solve the bug and move on—though, oftentimes, you find yourself frustrated by time-wasting bugs. This is especially true when working in corporate environments where you might be dealing with software that is not open source. The developers may not strive to keep the code well-organized as they would in open-source projects, so you often find a mess of issues scattered throughout the code.
00:03:10.159 As a Rubyist, you know that Ruby is a scripting language that does not require compilation. It runs exactly as written, enabling a great degree of introspection and reflection. This means you can check live objects when working with them and inspect the running program. Ruby excels in metaprogramming, which opens the door for alternatives like Pry.
00:03:42.840 I apologize if I call it 'pre' instead of 'pry,' as we tend to use 'pre' in Italy. Pry serves as a powerful alternative to the standard IRB for Ruby users. How many of you use Ruby on Rails? And how many of you use Ruby without Rails? Most of the time, when you open IRB, it's the default Ruby console where you can play around with the code. Pry offers a powerful alternative to IRB, with features like syntax highlighting, a flexible plugin architecture, and runtime invocation.
00:05:15.520 Pry is an acronym that stands for 'Read-Eval-Print Loop.' The simplest possible REPL in Ruby started with just 75 lines of code. Essentially, it allows you to read a line of code, evaluate it, and print the output. This loop is what makes Pry so outstanding compared to IRB and other alternatives.
00:05:48.000 Pry comes with many useful features such as syntax highlighting and tab completion, which is hugely beneficial for those of us who can be a bit lazy with typing. One impressive feature is the underscore and double underscore, which allow you to access the last outputs directly within Pry. It significantly changes the way I debug or try to fix code.
00:06:22.240 Inside the Pry console, you can view the documentation for a method or class, and most importantly, you can check the source of a specific method. More often than not, we use methods or objects that reside in our projects, and they often aren't documented because many developers may overlook documentation, hoping that Ruby's self-explanatory nature will suffice. The command 'ls' allows you to list all local variables in your current context. The 'cd' command is another fascinating feature that lets you navigate as you would in a Unix system, moving into objects instead of directories.
00:07:00.039 For instance, if you have an instance of a User model, you can 'cd' into that object and access all its methods directly. This means you can call private methods without needing tedious workarounds. Another excellent feature is the 'edit' command, which opens your preferred editor directly in the file of the specified method or class.
00:07:42.080 The binding.pry command is significant because it allows you to pause execution at a specific point in your Ruby code and access all the context around it. You can put this single line anywhere in your Ruby file or Rails application, and when your code executes that line, it will open a Pry shell right there.
00:08:23.760 This capability gives you access to real data flowing through your application, which is incredibly valuable for understanding what is happening during execution. For example, if you have a Rails controller behaving strangely, you can simply add 'binding.pry,' refresh your browser, and the console will allow you to inspect the data flowing through that controller at that exact moment.
00:09:01.960 Why is this important? Well, when you open the Pry console at that line, you can access all the variables in that exact call. If you remove the binding.pry command, your application will continue to run as normal. This lets you view the actual, real-time data when debugging, check documentation, and move around to assess what is going on.
00:09:43.840 There is a useful command in Pry called 'play,' which allows you to run a line of code without stepping through it one line at a time. For those of you familiar with the debugger, you know you can use 'next,' but with 'play,' you can quickly copy, paste, and execute a line without having to step through it.
00:10:29.240 Pry also boasts a wide array of plugins. One notable plugin is 'pry-remote,' allowing you to connect to a running server's REPL over TCP, providing a seamless debugging experience without needing to start the REPL manually every time. Another recent addition is 'pry-byebug,' which lets you navigate through your program's stack using up and down commands, enhancing your debugging workflow.
00:11:21.960 Pry also introduces 'pry-rescue,' which automatically opens the Pry console when an exception occurs, so you don't need to manually insert binding.pry in your code to stop and investigate. This automatic approach can significantly alleviate time when debugging.
00:12:02.080 Now, I would like to demonstrate this in action. I have written a simple Ruby program that simulates the Tower of Hanoi problem. It consists of just a couple of files. I will run the demo now, which initializes the Tower of Hanoi and attempts to solve it. Let's proceed with running the Ruby demo.
00:13:03.600 I realize I have not finalized the changes from earlier, so there might be an issue. Upon executing the code, we encounter an exception. To find the problem, I'll look at line 15, where the error originates. I will put a binding.pry here and rerun the code. Now that we have paused the program where I placed the binding.pry, we can examine the context of the program at that point. The comments provided by Pry will explain exactly where I am in my code.
00:14:54.240 From this point, I can see that we are indeed inside the Hanoi object, and I also have access to all methods and private methods associated with it. The debug process is straightforward, as I will check the stack to identify what has caused the problem. If the stack is not empty, I will continue iterating. Let's check the invocation again.
00:15:56.560 We will keep moving forward until we find an issue, and we can see that at this point the stack is empty. Now, I need to check the status of my Tower of Hanoi to understand what is going wrong. To assist with this, I have added a display method that allows me to visualize the current state. I'm noticing that the sizes of the disks indicate something may be off.
00:16:42.440 Upon further inspection, I realize that I am missing the smaller disks. As I re-evaluate my code, I recall inserting a double pop by mistake. I will change this back to a single pop, allowing me to execute the code once more.
00:17:55.480 After making my adjustments and rerunning the code, I encounter another exception, but this time the issue lies in a different line. The code indicates that I cannot place a disk from stack three to stack two. I will check the current state of my Tower of Hanoi again as before.
00:18:29.440 Upon analysis, it would appear I have made an error in my conditions. I will change this condition and rerun my code.
00:19:10.080 This time, all is well; I have arrived at the correct solution. I also prepared a mini test file for this project.
00:20:03.559 I run my tests now and encounter one failure.
00:20:36.760 Now it's a bit tedious to open the file and add another binding.pry for debugging. Let's explore how we can use 'pry-rescue' to simplify our process.
00:21:20.120 I will open my project repository and include 'pry-rescue' in my test file for integration with different testing frameworks. Now, when another error arises, I will see the Pry console automatically open.
00:22:32.440 This means I can investigate the state without painstakingly adding lines of binding.pry every time there's an issue.
00:23:12.640 I want to ensure I know where I am in my code to trace back the problem correctly. The ability to print the current context dramatically reduces the time needed to debug.
00:24:09.680 Next, we will check our Hanoi instance as it is currently initialized. The assertion test will evaluate whether it solves correctly and match the expected values.
00:25:46.120 Instead of typing everything out, I will utilize Pry to insert the last lines of code I need, allowing me to assert my conditions effectively.
00:26:45.480 This method streamlines my testing process. It saves me time and minimizes the need for unnecessary repetitive tasks.
00:27:51.760 I also want to show you how to extend Pry to meet your needs. For example, I will define a block command in Pry to streamline some of our work.
00:29:55.640 When I return to my project, I can implement this to create commands for more complex functions. Using Pry allows for these custom adaptations that can improve workflow.
00:31:29.200 Overall, I suggest you not hesitate to read or even change the code of the libraries you use. Don't be afraid to access and inspect your gems.
00:32:55.639 In summary, if you find code that's outside your control, remember you can edit it and quickly understand the changing dynamics. This immediate access to the console via Pry has transformed my debugging process.
00:34:12.440 Tools such as the help command can illuminate many options available to you in Pry, making it efficient for debugging within Ruby.
00:34:47.560 Thank you for your attention today. I hope this discussion of Pry has illustrated its value in debugging Ruby applications efficiently, and I encourage everyone to try it out and see the difference it can make.