X

NV5 Geospatial Blog

Each month, NV5 Geospatial posts new blog content across a variety of categories. Browse our latest posts below to learn about important geospatial information or use the search bar to find a specific topic or author. Stay informed of the latest blog posts, events, and technologies by joining our email list!



From Image to Insight: How GEOINT Automation Is Changing the Speed of Decision-Making

From Image to Insight: How GEOINT Automation Is Changing the Speed of Decision-Making

4/28/2025

When every second counts, the ability to process geospatial data rapidly and accurately isn’t just helpful, it’s critical. Geospatial Intelligence (GEOINT) has always played a pivotal role in defense, security, and disaster response. But in high-tempo operations, traditional workflows are no longer fast enough. Analysts are... Read More >

Thermal Infrared Echoes: Illuminating the Last Gasp of a Dying Star

Thermal Infrared Echoes: Illuminating the Last Gasp of a Dying Star

4/24/2025

This blog was written by Eli Dwek, Emeritus, NASA Goddard Space Flight Center, Greenbelt, MD and Research Fellow, Center for Astrophysics, Harvard & Smithsonian, Cambridge, MA. It is the fifth blog in a series showcasing our IDL® Fellows program which supports passionate retired IDL users who may need support to continue their work... Read More >

A New Era of Hyperspectral Imaging with ENVI® and Wyvern’s Open Data Program

A New Era of Hyperspectral Imaging with ENVI® and Wyvern’s Open Data Program

2/25/2025

This blog was written in collaboration with Adam O’Connor from Wyvern.   As hyperspectral imaging (HSI) continues to grow in importance, access to high-quality satellite data is key to unlocking new insights in environmental monitoring, agriculture, forestry, mining, security, energy infrastructure management, and more.... Read More >

Ensure Mission Success With the Deployable Tactical Analytics Kit (DTAK)

Ensure Mission Success With the Deployable Tactical Analytics Kit (DTAK)

2/11/2025

In today’s fast-evolving world, operational success hinges on real-time geospatial intelligence and data-driven decisions. Whether it’s responding to natural disasters, securing borders, or executing military operations, having the right tools to integrate and analyze data can mean the difference between success and failure.... Read More >

How the COVID-19 Lockdown Improved Air Quality in Ecuador: A Deep Dive Using Satellite Data and ENVI® Software

How the COVID-19 Lockdown Improved Air Quality in Ecuador: A Deep Dive Using Satellite Data and ENVI® Software

1/21/2025

The COVID-19 pandemic drastically altered daily life, leading to unexpected environmental changes, particularly in air quality. Ecuador, like many other countries, experienced significant shifts in pollutant concentrations due to lockdown measures. In collaboration with Geospace Solutions and Universidad de las Fuerzas Armadas ESPE,... Read More >

1345678910Last
«May 2025»
SunMonTueWedThuFriSat
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567
11962 Rate this article:
5.0

New in IDL 8.5, Function Pointers and Dynamic Methods

Jim Pendleton

One side effect of adding a Python language bridge to IDL in 8.5 is the exposure at the API level of a couple new ways to call IDL object methods.

Even if you never write code that takes advantage of these features, you will want to be aware of the implications of the new language syntax if you should ever encounter it in the handiwork of someone else.

The original motivation for the features was to expose Python syntax and constructs in an efficient way through IDL, specifically through classes that inherit from IDL_Object. Changes to the interpreter were made to support this.

These techniques are now documented for the public and can be used in your own code. They are available to you if you find their patterns appropriate for your own applications.

Function Pointers

Conceptually, a "function pointer" in IDL is just a new way to treat an IDL_Object reference as if it is a function.

For example, I may have defined a class "my_class" that inherits from IDL_Object. It's instantiated the usual way.

IDL> mine = my_class() ; or OBJ_NEW('my_class')

The new syntax allows me to "call" the object reference as if it is a function, if I have set COMPILE_OPT to IDL2 or STRICTARR first.

IDL> compile_opt idl2
IDL> result = mine(1,2,3)

At run time, the interpreter sees the object reference associated with the variable "mine" and notices the left parenthesis that immediately follows. The interpreter then checks if this object's class has implemented the method "::_overloadFunction", inherited from IDL_Object. If so, it then calls that method with the parameters and keywords in the argument stack. If the method is not implemented, an error is thrown.

The implementation of the method in "my_class" might generate a product of the three arguments, and would be implemented like this

function my_class::_overloadFunction, arg1, arg2, arg3
return, arg1*arg2*arg3
end

Left as an exercise for the reader is determining the call hierarchy if there is also, say, a "regular" IDL function with the same name as the variable represented by the object reference.

In the above code, consider the possibility that there is a standard IDL function that has the same name as the variable "mine", for example "FUNCTION mine, arg1, arg2, arg3".  Will that function be called or the object's ::_overloadFunction method?

Will the behavior depend on which routines have been compiled or resolved first?

Also left as an exercise for the reader is the test of using ::_overloadFunction when subclassing or adding to IDL_Object subclasses that already have built-in special syntax for interpreting left parentheses, such as LIST and HASH

Dynamic Methods

The IDL_Object::_overloadMethod represents a second new syntax introduced in IDL 8.5, also intended primarily to support the Python bridge. The intended functionality itself is described in the following way in the documentation.

By implementing _overloadMethod on your class, users can then make an arbitrary method call on an object reference.

Practically, the new behavior comes into play when the "." dot operator is encountered by the interpreter next to a variable or expression that is an object reference. In some ways this is analogous to the new behavior when a left parenthesis is interpreted and associated with the function pointer syntax described above.

Continuing with the same object created in the earlier example, let's say we have

IDL> data = mine.mymethod(1,2,3)

If I have a method on this class named "::mymethod", then it should be called first.  This is standard behavior in IDL 8.4 and earlier. However, if that method does not exist, rather than issuing an error there is a new behavior in IDL 8.5, an additional step.

If I have defined a method named ::_overloadMethod in "my_class", that method will be called. Its first positional argument will be the uppercase version of the string following the dot operator, up to but not including the left parenthesis. In this example, the string will be "MYMETHOD".

Any positional or keyword parameters are then passed through to the implementation of ::_overloadMethod in the standard way.

See the example in the IDL 8.5 online help associated with IDL_Object. As originally conceived, ::_overloadMethod is a mechanism for calling methods on objects referenced within the class rather than methods of the class itself. That is, the object implementing ::_overloadMethod is a proxy for contained objects.

However, the string that's passed as the "method name" may or may not actually be the name of a method in any class whatsoever.  It's just a string at the interpreter level.

A class could use the string being passed as "method name" in any way imaginable.

One might easily abuse this to produce unintelligible code, for example, where one simply doesn't care to use quotation marks.

The only rule is that the string must be valid as a theoretical method name, using appropriate characters.  For example, I can call a "method" named "ABC123", but not "123".

Consider this example

IDL> a = {myo, inherits idl_object}
IDL> .compile
- function myo::_overloadmethod, supposedmethodname, a, b, c
- help, supposedmethodname
- return, 0
- end
IDL> r = (myo())._o080o_()
SUPPOSEDMETHODNAME      STRING    = '_O080O'

The interpreter syntax change in IDL 8.5 also applies if the CALL_METHOD function is used instead, so one could dynamically create a "method" name to be called.

IDL> s = call_method(IDL_VALIDNAME(SYSTIME(), /CONVERT_ALL), myo())
SUPPOSEDMETHODNAME      STRING    = 'WED_JUL_29_12_40_37_2015'

Be kind to future generations of coders and use these new features wisely and after much consideration.

 

Please login or register to post comments.