Tuesday, September 27, 2005

Dynamic Programming

Magik gives you the ability to call methods without knowing the name of the method at compile time. It does this via the perform method. With the perform method, which is defined on object and can therefore be sent to any type of object, takes a symbol as the first argument. This symbol is the name of the method to call. Any subsequent arguments to the perform method are passed to the invoked method. Here's an example:

MagikSF> r << rope.new()
$
sw:rope:[1-0]
MagikSF> r.add("hi")
$
"hi"
MagikSF> r.perform(:size)
$
1

You can do this with any type of method, including the square brackets method, as long as you create the symbol correctly with the vertical bars:

MagikSF> r.perform(:|[]|, 1)
$
"hi"

And you can even use the setter method:

MagikSF> r.perform(:|[]<<|, "joe", 1)
$
"joe"

MagikSF> r[1]
$
"joe"

Notice the strange order of the arguments to this method. I would have thought the index would have been the first argument, but it's not.

So, we can build up calls to objects by creating strings and then sending them as method names (really messages) to the object. What if we want to send a message to an exemplar where name of the exemplar is derived dynamically? To do this you use the square bracket method on the package containing the exemplar. Here's an example:

MagikSF> !current_package![:rope]
$
sw:rope:[1-1]

This stuff isn't used that much, but it can come in handy.

Thursday, September 22, 2005

Parsing Strings

A client new to Magik recently contacted me. He was frustrated with his failure to find out how to parse a string. While Magik, with its class browser, it much easier than most languages to figure this out, it can still be frustrating. The help files shipped with Smallworld are excellent and I recommend reading them often. They are very voluminous, but just read the section that prompted your search and then remember to return to it whenever you want a better understanding of the concept in question.

That said, the help files aren't the best place to search for this information. The class browser is usually your best bet. Fire that baby up (F3 F3) and enter "string" for the class. Now you have to guess what the method will be called. "parse" would certainly be your first guess in this case. Unfortunately, that isn't what the method is called and hence my client's frustration. Here there should be a topic in the help files to cover this very important area, but there isn't. So now you just have to guess. What is parsing? It is splitting up one string into many strings. So, if you search on "split" you'd find the method split_by(), which takes a single argument: a character upon which to split the string. Here's an example from the Magik prompt:

MagikSF> "123,456,hi joe".split_by(%,)

$

sw:simple_vector:[1-3]

MagikSF> print(!)

$

simple_vector(1,3):

1 "123"

2 "456"

3 "hi joe"

Here we split a string using the comma character as a separator. Note that a character object is created with the percent sign (%). This is just like the colon creates a symbol object and quotes create string objects. Also, the variable "!" is always set to the last value returned to the Magik prompt, hence I could print out the vector returned from the method split_by() using it. the split_by() method is sent to a string and it returns a vector of the parsed strings.

This client also wanted to turn a string of number characters into a number. There are a couple of ways to do this but the most natural is to use the as_number() method on string. This pattern is used often and many objects have as_object_class methods defined on them for conversion. Here is an example:

MagikSF> "123".as_number()
$
123

Why this blog?

This is my effort to collect some useful Magik programming hints, snippets of code, and discussion about the language. This programming language is only used inside of GE's Smallworld GIS product and hence has a very restricted audience compared to general programming languages. I am a principal consultant at Red Planet Consulting and I frequently teach classes on Smallworld and Magik. A number of students have asked me if there is a book that teaches this language. There is not, though I've thought about writing one many times. This is an area where I can collect my musings on the topic.

Bill