Scripting is a great tool in many applications. It’s an easy way to open up the functionality to other people. This blog is about some of the generic issues involved in adding scripting to your application. My own choice of script language is normally Qt Script or, when this isn’t possible, Python. But the advice given here applies to all script engines.
Plugins has many of the same advantages and disadvantages as scripting, but are usually (for Qt applications) written in C++ and Qt, which means they are not portable. On the other hand, plugins written natively have the full advantage of the Qt framework, where a script system only offers what you allow it to use. Some applications have plugin structures that are done with scripts.
When adding scripting to your applications, there are a number of pitfalls you have to be aware of. I’ll mention some of these here. There are many others, and I advise every company that does scripting to make sure their developers really know what they are doing in this area.
The first advise I’ll give is to treat all scripts as hostile code. Hostile code is any code written by people that have other goals than improving the application. Treating script code as hostile means you have to test and check every single thing the script does. The reason for this way of thinking is that many of your users don’t understand the scripting framework completely, so they make mistakes. It’s like the old developer saying: “If you think your application is crash proof, let your grandmother test it.” By treating the code as hostile, you make sure your users don’t by accident destroy the application. And of course, there might actually be hostile users.
Do not make the mistake of assuming you can imagine the needs of your users. If you do this, you will limit the functionality of the script framework in your application and the users will not have the freedom that scripting should offer. Instead, make sure you have a system implemented where you can get feedback from your users. This is even more necessary than a feedback for the normal application usage, since this is usually easier to think through. Open up the script framework as much as possible by offering a lot of possibilities.
Don’t ever allow scripting to not be unit tested. It is incredibly important to have a regression test suite, so you will know if work done on the scripting breaks old scripts. This isn’t like an application, where the users might be able to perform the same task by using another feature set in the GUI. These scripts just run, and often your customer will need to bring in a consultant to fix them if you break the script. And you will break them, if you don’t have regression tests set up. Script engines are difficult to implement, and even harder to maintain.
You can not allow the script to save scripts to disk, if they are loaded by the application on runtime. This is by definition the way to open your application to virus script makers. Allowing scripts to be saved to disk is okay, if the application only loads it by user interaction – for example choose from a list of available scripts in a menu.
The last advise is to avoid pushing your source code policies over the scripting engine idioms. For example, you might have a policy not to use exceptions in Qt code. (This is an example from a customer, not my choice.) Don’t make the mistake of applying this policy to your scripts. Qt Script uses exceptions to communicate errors, so you should do this too. This doesn’t in any way affect your C++ code, but means you follow the standard for the script language and framework. This makes it easier for your users to pick up standard books on the language and use these with your scripting engine.
Finally, I will give this advise: Unless there is a very good reason against it, offer your users the choice of a great scripting engine. For anything but toy applications, it’s hard not to imagine nice possibilities from a script engine.