DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
View Events Video Library
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • Automated Testing: When to Start?
  • How to Install Runtime Fabric in Linux 7.8 (localhost)
  • Robust Exception Handling
  • Unraveling Lombok's Code Design Pitfalls: Exploring Encapsulation Issues

Trending

  • Auto-Scaling DynamoDB Streams Applications on Kubernetes
  • Best Practices for Developing Cloud Applications
  • Modular Software Architecture: Advantages and Disadvantages of Using Monolith, Microservices and Modular Monolith
  • Choosing the Appropriate AWS Load Balancer: ALB vs. NLB
  1. DZone
  2. Data Engineering
  3. Data
  4. What Function Called My Function

What Function Called My Function

Gary Gilbert user avatar by
Gary Gilbert
·
Feb. 06, 08 · News
Like (0)
Save
Tweet
Share
5.10K Views

Join the DZone community and get the full member experience.

Join For Free

I recently came across a question on the Adobe forums about being able to tell who called a certain function in a base component (the "super"). The first thing that came to mind was: is this even possible? The answer is: Yes of course it's possible!

The full question by Spike H:

I have written a utility component (test1 below) and want to keep track of what external functions call the functions within my component. Other programmers create a component (e.g. test2 below) that extends my utility component and then their functions call my functions. I want to record metric data to determine how much use my functions are getting and from where. I've used the getMetaData() function inside my functions, but that only gives me the name of the component that extends my component (in this case test2), not the specific function that called my function (in this case functionAtest2).

That piqued my interest, I figured there had to be a way. I know when you get an error you also get a stack dump which gives you the entire call stack, so the information is available (getting warmer). In ColdFusion when you do error handling there is also a cfcatch variable called tagContext that contains a quasi call stack (looking better). So that means that we need to have access to the tagContext, and as far as I know it is only available when an error occurs, so lets cause one (now we are cooking!).

What we will do then in order to achieve our purpose is create a utility function that forces an error, at the same time we will wrap the cfthrow in a try/catch block and then process the tagContext to determine the calling function.

The entire component looks something like this:

<cfcomponent>
<cffunction name="functionToCall" returntype="void">
<cfoutput>called from #calling()#<br></cfoutput>
</cffunction>
<cffunction name="calling" output="true" returntype="string">
<cftry>
<cfthrow type="Application">
<cfcatch type="any">
<!--- the current template is always the template that actually does the calling, since this cfc is extended the current template
will be the template that extended this component --->
<cfset thispage = getcurrenttemplatepath()>
<!--- I put the tag context in a local variable not exactly necessary but ... --->
<cfset variables.tagcontext= cfcatch.tagContext>
<cfloop from="1" to="#arraylen(variables.tagcontext)#" index="i">
<cfif variables.tagcontext[i].template eq thispage>
<!--- return the calling function or store the information somewhere --->
<Cfreturn #mid(variables.tagcontext[i].raw_trace,findnocase("$func",variables.tagcontext[i].raw_trace)+5,(findnocase(".runFunction",variables.tagcontext[i].raw_trace)-(findnocase("$func",variables.tagcontext[i].raw_trace)+5)))#>
</cfif>
</cfloop>
</cfcatch>
</cftry>
</cffunction>
</cfcomponent>

I saved the component as test.cfc and then created a second component (test2.cfc) that extends my first test component:

<cfcomponent extends="test">
<cffunction name="callTheFunctionInSuper" returntype="void">
<cfset functionToCall()>

</cffunction>

<cffunction name="callTheCalling" returntype="void">
<cfset callTheFunctionInSuper()>

</cffunction>
</cfcomponent>

Just to make things a bit more interesting and to see how my example code handles the tagContext I created two functions. callTheCalling calls callTheFunctionInSuper which then calls functionToCall.

I then created a cfm page to actually do the calling.

<cfscript>
mytest = createObject("component","com.gg.test1");
mytest.callTheCalling();
</cfscript>

And voila! The output looked like:

called from CALLTHEFUNCTIONINPARENT

Cautionary Note:

While an interesting idea to track the usage of a component I would not recommend deploying this to a production system without some serious thought. You would need to decide on the best approach as to provide the best response time (perhaps in a separate thread) so that execution would continue without interuption.

 

Execution (computing) Data (computing) Testing Production (computer science) Blocks Programmer (hardware) IT

Published at DZone with permission of Gary Gilbert. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Automated Testing: When to Start?
  • How to Install Runtime Fabric in Linux 7.8 (localhost)
  • Robust Exception Handling
  • Unraveling Lombok's Code Design Pitfalls: Exploring Encapsulation Issues

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: