X
9285 Rate this article:
No rating

Overloading Objects in IDL

Anonym

One semester in college, I attended an informal class on object oriented programming in Python. On the first day, the professor asked if any of us had experience in object oriented programming. I told him that I use IDL, and he laughed me off and said, "IDL is not a real object oriented language." 

I personally think that IDL has many object oriented capabilities, and I'm still new techniques. Because IDL is an interpreted language, I have to say that it is very easy to develop classes, and object oriented programming in IDL is certainly nothing to be afraid of.

In this week's IDL Data Point article, I will discuss overloading operators of existing classes. Any object in IDL, including ones provided in the installation, can be overloaded by writing a new object class that uses inherits in the object class definition. In fact, some objects, such as IDL_OBJECT, are designed for the purpose of being overloaded.

Here is an example I made up: I want to use a list, but I want my list to do a little bit more than the simple LIST object in IDL (note that IDL's documentation specifies the lists and hashes as "compound data types," but underneath the hood, they are simply object classes). This fancy list will only allow numbers to be added. It must also have the ability to multiply every value by a specified factor, as well as the ability to increment all values by one.

Define the Class

For a lack of a better name, I will call this new list a "Fancy_List." The definition would look like this:

 

pro Fancy_List__Define
  
  !null = {Fancy_List, inherits List}
  
end

 

"Fancy_List" is now defined as a subclass as a list. 

 

fl = Obj_New('Fancy_List')
PRINT, Isa(fl, 'List')

IDL prints 1.

This means that a fancy list is a list, and a very fancy one at that.

Overload the ::Add Method

Since this list should only allow numeric values, the Add method needs to be overloaded. This can be done by writing a method Fancy_List::Add. In this example, any value passed in that is not a number will be quietly ignored. After performing the check, the code then calls down to the superclass ::Add method. Keywords are simply passed through via _REF_EXTRA (this is used instead of _EXTRA so that unnecessary copies of keywords are not made).

 

pro Fancy_List::Add, value, index, _REF_EXTRA=extra
  
  if ~Isa(value, /NUMBER) then return
  
  self.List::Add, value, index, _EXTRA=extra
  
end

 

Implement a ::Multiply Method

I will write a new method called ::Multiply that multiplies every value by a given factor. This method name is unique to the fancy list, since LIST does not have such a method, so it does not overload anything.

 

pro Fancy_List::Multiply, multiplier
  
  for i=0, self.Count()-1 do begin
    self[i] *= multiplier
  endfor
  
end

Overload Operators

Since List inherits IDL_Object and Fancy_List inherits List, then the fancy list can overload any of IDL_Object's operators. Here is an example of overloading the ++ operator. This operation will increment every value in the fancy list by one.

 

pro Fancy_List::_overloadPlusPlus
  
  for i=0, self.Count()-1 do begin
    self[i]++
  endfor
  
end

 

Example in Action

Now that it's all assembled, let's click the Compile button and try it out!

fl = Fancy_List()
fl.Add, 'A'
print, fl.Count()

IDL prints 0, since the fancy list ignored the string value 'A.'

fl.Add, [1,2,3,4], /EXTRACT
PRINT, fl

IDL prints:

       1
       2
       3
       4

 

fl.Multiply, 2

PRINT, fl

IDL prints:

       2
       4
       6
       8

fl++
PRINT, fl

IDL prints:

       3
       5
       7
       9