TL;DR: Callers and Stack Traces are two indispensable tools for debugging code and Ray makes it simpler than most fully-featured debugging environments. This article covers how to both understand what they are and how to use them.

⚠️ If you’ve not already set up your environment, please read this post and make sure you have the free version of Ray installed.

Callers and Stack Traces

If you’re familiar with:

  • seeing a program crash and dump information on to a screen,
  • see PHP dump an error out into the browser,
  • or have done enough debugging to understand stack traces and callers then all of this will seem familiar to you.

If not, no big deal. The concepts are really easy to understand but it’s very useful stuff to know how to read and apply when figuring out how a specific application is behaving.

Not only does this identify how to the flow of control is happening in your application but it also helps you to see how the overall application and, in our case, that’s WordPress, is leveraging our code.

Defining The Terms

Before making changes to our plugin and seeing how we can take advantage of Ray to see how to understand what we’ve done, let’s make sure we have a working definitions of the terms we’ll be using in this article and throughout the rest of the series.

  • Caller. A caller is simply the function that invoked the function that’s executing. For example, if you have a function called printName and it accepts a single argument called $name and then you have a function called sayHello and sayHello passing information to printName then sayHello calls printName. So all that to say, sayHello is the caller for printName.
  • Trace. When you view a trace (or a stack trace as its more commonly called) of code, then you’re seeing a list of all of the functions that were called that lead up to the point that you view the trace. The term “stack trace” is because when you’re reading the list of functions leading up to the function where execution stopped, it’s rendered as a stack of function calls.

With those terms defined, here’s how we may want to use them in practice:

  • We want to verify the function we expect to call is calling our function.
  • We want to see what series of function calls lead to the point of execution in our code where we’ve halted execution.

The first is for viewing the caller, the second is for viewing the stack trace.

Got it? Even if not, no worries! The following code should help illustrate this point.

Our Plugin: Calling and Tracing

We’re going to continue working with the plugin we’ve been building through out this process. To the first thing we’re going to do is take this block of code:

And then move it to its own function. The code should be self-explanatory but we’re basically taking that code and moving it into its own function called getUserCapabilities and it will accept an instance of WP_User.

The code comments should easily explain but don’t hesitate to let me know, if not.

Now that we’ve refactored the code a little but, we can start taking a look at callers and stack tracing.

💡Here’s a thing to keep in mind, though: Recall that the function we have hooked to the the_content filter is anonymous (it’s also referred to as a closure in PHP, but the details of why it’s a closure are beyond the scope of this article).

Anonymous functions yield objects of this type. This class has methods that allow further control of the anonymous function after it has been created.


Also, remember to make sure you’re logged into your WordPress installation as the code assumes there is an active user. If your not, the plugin should still work but the output in Ray will be different.

What’s The Caller?

Now that we’ve extracted the code necessary for getting a few of the user’s capabilities, we can leverage one of Ray’s features to see who’s calling the function.

Sometimes you want to know where your code is being called. You can quickly determine that by using the caller function.


So, first, make sure that your anonymous function is calling our new function:

Then, in the new function, add the following line at the top of the function:

When you do this, reload a single post page and review what Ray has to show. If you’ve done everything correct (and haven’t removed anything else), then this should be visible in your Ray screen:

Notice, it’s the namespace that we’re using in our plugin followed by the {closure} placeholder (again, because we’re using an anonymous function to invoke the new function).

But you get the idea, right? So let’s take it a step further.

What’s The Trace?

Ray’s trace functionality is a really cool function because you can see how your code gets accessed from the moment WordPress itself is invoked.

If you want to see the entire backtrace, use the trace (or backtrace).


Imagine if you load a page and then you can see from the start of WordPress’ execution everything that was called leading up to the point of your specific function. Sounds cool right?

So in the function that we’ve introduced in this version of the plugin add the following line of code:

Then refresh the page and view Ray. You should see something like the following:

Neat, right? From there, you can verify that your code is being called as expected from the proper area in WordPress. Further, you can look up any functions you don’t recognize in the Developer Resources to further understand what’s happening.

🐛 For those familiar with debugging, you may find this simple. In one way, it is, but I’ve also found that spinning up an entire debugger just to hit a breakpoint to see output Ray can generate with a a couple of function calls far more efficient.

On top of that, there are additional debugging techniques that can be done with Ray. And I’ll cover those later.

🔖 Remember The Tag

Recall I’m using the develop branch of the repository for each article. After the article, I’ll merge the contents of develop into main and then I’ll tag the version with the date the article was publishing. 

The tag for this article will be 19012022.

We’ll continue to look more into what Ray can do for us within WordPress in the next article.

☕️ Enjoying this guide? Consider Buying Me a Coffee to support these longer form articles!