Objects


It is frequently useful for applications to store information between runs. In general, if it is important enough to ask the user, it is important enough to remember. IDL provides a handy routine app_user_dir to get a directory to store this type of information, but you are on your own reading and writing these preferences (unfortunately, pref_set and pref_get don't allow application defined or user-defined preferences). MG_Prefs (code, docs) handles the dirty work for you by creating and restoring a SAV file for each of your preferences. This is a bit heavy-handed, but it means you store nearly anything as a preference value.

The class is intended to be simple to use. To store a preference do

prefs = obj_new('mg_prefs', author='mgalloy', application='myapp')
prefs->set, 'last_edited', 'myfile.txt'

Then in a later IDL session this preference can be retrieved with

prefs = obj_new('mg_prefs', author='mgalloy', application='myapp')
lastEdited = prefs->get('last_edited')

The template class is the basis for all the output in IDLdoc. In the process of releasing IDLdoc 3.0, some additions were necessary to facilitate outputting more complex hierarchical data.

Previously, the template process method took a structure argument and substituted variables in the template by the corresponding field name in the structure. The new version uses objects (but still allows structures). Any object with a getVariable method that follows the following signature:

function classname::getVariable, name, found=found

can be passed to the MGffTemplate::process method. When a name is encountered in the template, the template object calls getVariable with the variable name. This is much more flexible because variable requests can be handled in many ways: inherited from a parent class, delegated to another object, retrieved from a member variable, or retrieved in some other way (array, hash table, etc). Also, output can added to an object hierarchy by just adding a method instead of creating special structures.

The files needed to use the template are the MGffTemplate class (docs) and the MGffTokenizer class (docs).

See these previous posts about the template class.

True random numbers cannot be generated by a computer, but there are devices that can be connected to a computer that will generate true random numbers. Since not everyone has one of these devices, there are services that make these random numbers available through the internet.

Try random.org for random integers, sequences, and strings derived from atmostpheric noise. I have a simple class that uses the new IDLnetURL to access the website. It can be used like:

IDL> rnd = obj_new('MGrndRandom')   
IDL> result = rnd->getIntegers(5, min=0, max=99, error=error)
IDL> help, error
ERROR           LONG      =            0
IDL> help, result
RESULT          LONG      = Array[5]
IDL> print, result
          63          63          88          62          53

The class is available in my library (source, docs).

Continue reading "True random number generators."

I added methods to MGTestCase which are called before (setup) and after (tearDown) each test. Uses of these methods would be to create (and destroy) some common data for each of the tests in the MGTestCase, to time each test, or to do any task that must be done on a test-by-test basis as opposed to before and after all the tests in a MGTestCase (init and cleanup do that).

See "Unit testing framework" for an overview of the unit test framework.

Here's an archive of all files needed and the docs for all the source code.

Templates are tools for creating text output reports. The beauty of templates is that they allow a separation of the code that generates/calculates information from the code that produces the output. The template code produces the output and is done in plain text in the type of output desired with a few directives that are used to insert the real information, check conditions, do loops, include other files, etc. This article will demonstrate more features than my original post about templates. The demo program mg_report_demo.pro (docs) uses three templates to create its output: the main template, the header, and the footer.

The files needed to use the template are the MGffTemplate class (docs) and the MGffTokenizer class (docs).

Continue reading "Report generation: more about templates."

Template classA class similar to MGffTemplate is used in IDLdoc to produce all its output. When I changed from a bunch of print statements scattered over various methods of a class to templates where all the output is in a template file, it was a lot easier to focus on the content of the output. If you need to generate text-based reports (HTML, XML, LaTeX, DocBook, etc.) from IDL, I would suggest using this class.

The files needed to use the template are the MGffTemplate class (docs) and the MGffTokenizer class (docs).

Continue reading "Template class."

Screenshot of JPEG 2000 viewerA couple weeks ago, I wrote a demo program to view JPEG 2000 images as a "regular" widget program. Now I want to rewrite the same program as an "object widget," in other words write methods of a class instead of normal functions and procedures. You need to already understand the basics of object-oriented and widget programming in IDL to follow along with this example. The following files are needed for this program: mgtilejp2__define.pro (doc), mgobjectwidget__define.pro (doc), mg_object_event_handler.pro (doc), and mg_object_cleanup.pro (doc).

Continue reading "Object widgets."

One area that is sorely missing in IDL's library is more flexible collections. Sure, arrays are extremely powerful in IDL and we should try to use them whenever possible. But sometimes arrays are just not the right tool for the job. There are two main cases which arrays don't handle well:

  1. Arrays can't have zero elements.
  2. Adding an element to an array by concatenation repeatedly is extremely inefficient.

MGArrayList solves both of these problems. This is one thing in my library that I use on nearly every project.

I have a class on RSI's User-Contributed Library called Array_List which has most of the same functionality, but I wanted MGArrayList to have exactly the same interface as IDL_Container. So MGArrayList should do everything IDL_Container does, but for all types instead of just objects.

Source code and docs for MGArrayList, its iterator, and parent classes. I intend to implement other collection classes such as hash tables, sets, and trees over the next few weeks.