The main loop does three primary things: manages a Screen object, creates a Clock object that determines the framerate and processes events. For the main loop to do this, three objects must be created before the main loop starts.
The screen (the game window displayed on your screen) is created by constructing a new Screen object, passing to it the resolution you want to use. Note that Screen is a singleton class, SDL can only handle one screen surface at a time--trying to construct more than one Screen object will raise an exception.
Events are processed from a queue. Events arrive and are removed from the queue in the order they arrived. The EventQueue#each method will iterate over the events that have arrived, yield them to a block (just like an each method on an array) and remove them from the queue. In this example program, the block just checks if the event is a QuitEvent (one that is sent to your program when you close the window) and, if it is, returns from the main_loop method.
The framerate has to be limited in your games for better control. On modern computers, running a simple 2D game is an easy task. If left to run at its maximum speed, your game can run at hundreds or thousands of frames per second. This will use 100% of your CPU cycles and make it very difficult to control your game. In order to appear to have smooth animation 2D games only need to run at 30 or 60 frames per second
The class that helps you do this is the Clock class. After setting the object's desired_framerate attribute, it will pause the program for a short time every time you call its tick method.
Finally, at the end of the loop, the screen is filled with a grey color and updated. "Updating" the screen means to copy the screen surface from memory to video memory. Without calling update, your changes won't appear on the screen.