Advanced Magik Language

This page is intended for advanced programmers. See Magik Basic Language for more common language uses.

Compiling on the Fly

Do you need to load Magik code on the fly? Lets say a procedure is stored as a text join on an object and when you update the object, you want to let it run the procedure stored on the object.

The first thing you need is a handle to the string you want to "compile"
Then run this method: magik_rep.load_chunck(string.read_stream())

Stopping an Endless Loop on the Magik Prompt.

Have you started a (Near) endless loop on the Magik prompt? Here is a way to stop the loop.. You will need to open a Magik Input GUI from the opened application. In 3.X it was under Configuration or something like that. Once there type the following.

cli_thread.interrupt(_proc() _throw@wobbly _endproc)

From the Threads Manager, you can error the cli thread and it should stop the loop. Note the Threads Manager may only be available on 4.X releases.

Indirect Access to Globals

Have you wanted to write code that tests for the existence of a global variable without initializing the variable itself? You can use the following. Note the !current_package! could be replaced with packages such as sf_package.


Another way. Good for getting procs too…


You can "undeclare" a global by doing the following.


Adding a Mixin during a session

If you need to create a mixin in a current session and want to add the mixin ancestry to existing exemplars that you can't recreate during the session (record exemplars for example), you can add them using the following magik


Getting Current Dynamics

Here is a way to get the available dynamic variables in your current thread.

_for k,v _over _thisthread.dynamic_environment(_true)

Do you need to make a private method public?

Try this… Note you don't typically want to use this… But it is something to be aware of.


!!! THREAD !!! bpt on thread error

I was getting this when I was trying to do a code coverage analysis. The way to track this down is to add the following show() statement.

_method coverage_analyser.insert_bpts_in(method)

From the result you can add the problem method to coverage_analyser.excluded_code_vectors shared variable
    _local ex << message_handler
    _for m _over {:human_string|()|

Evaluating Strings into Magik results

You can evaluate a string like "_false" into a true Magik boolean.

MagikSF> !a <<
MagikSF> !a.add_last("_false")
MagiKSF> !a.evaluate() = _false

Temporarily Remove Method Functionality

Have you tried to use a method like split_by() only to see your leading and trailing spaces disappear? Here is a way you can overwrite the default behavior.. In this case we replace the trim_spaces() method with a simple procedure, run the split_by() and restore the original behavior.

    _local data
    _local str << " this is, a test ,  ,,"
    _local oProc << charindex_mixin.method(:trim_spaces|()|).value 
        charindex_mixin.method(:trim_spaces|()|).value << 
                    >> _self 
        data<< str.split_by(%,,_true)
        charindex_mixin.method(:trim_spaces|()|).value << oProc

Lexicographic Sorting

Lexicographic sorting is sorting strings like in a dictionary. When sorting strings, there can be special characters like ï, é and so on. The special characters do not sort on the base character, but differently as is shown by the following example:

MagikSF> %ï _cf %j
MagikSF> %i _cf %j

Here is a simple solution to the Lexicographic sorting problem with special characters.
    _local l_special_chars << property_list.new_with(%ï,%i, %ë,%e, %ö,%o)
    _local l_normalise << _proc(a) 
                      _import l_special_chars
                      _local l_result << ""
                      _for i_char _over a.fast_elementS()
                          l_result +<< l_special_chars[i_char].default(i_char)
                      _return l_result
    _local l_list << {"mals", "maak", "mazk", "maïs"}
    _local l_sorted_list << sorted_collection.new_from(l_list,
                                   _import l_normalise 
                                   _return l_normalise(a) _cf l_normalise(b)
1     "maak" 
2     "maïs" 
3     "mals" 
4     "mazk" 

Alternatively one may use text translators, _false).translate(, _true).translate("maïs"))

Renaming Methods

You can rename a method using the following. This is great to implement customized code without modifying the original code. This saves lots of time when TSBs or upgrades are installed!

meth << exemplar.method(method_name)
newMeth << :sw!+method_name
This functionality has been wrapped up in the attached fcsi_method_manip.magik file. Use fcsi_method_manip.fcsi_copy_method().

Handling "does not understand"

You can subclass the method does_not_understand(msg,private?). This allows you to support functionality when you do not necessarily know what is going to be called. A good example of this usage is in the Explorer Add-on for Pseudo Records located here. This passes unknown method calls to an owning object. Another interesting solution would be to create a in-memory object whose fields may be anything. You can intercept the non () methods and create in-memory object representations of those fields and they would act just like a field or slot on the original exemplar…


This needs a page of its own as there appears to be many things you can do with packages….

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License