Category Archives: Lua

Automatic Lua Properties

Automatic Lua Properties?

Starting with an example using the Lua specification and testing framework Busted:

Here is a little exercise in Lua metaprogramming.

Code

https://github.com/d-led/automatic-lua-property-tables

Spec: autoprop_spec.lua
Implementation: autoprop.lua

P.S. Other implementations: lua-users wiki: Automagic Tables

function argument sequence

In many APIs one is confronted with the question, which parameter stands for what.

Consider a call in a code you’re reading or trying to write:

is_funkier(1,2)

Is 2 funkier than 1 or vice versa? A long time ago I asked a childhood friends’ father if I could try program their game console. The response was that one has to know a programming language, such as basic. On a request to quote a bit from a programming language I heard “begin, end, goto”. ‘Sounds like English to me’, I replied,’I could do that’. And now, years later I want to program close to English: not Shakespeare but rather a DSL.

A minimal example of how I would improve the API above 1. Test:

And an easy way of implementing the API 2:

Depending on the usage, such constrained argument ordering may improve readability and thus perhaps reduce risks associated with writing code.

To further extend the DSL, further mechanisms can be used of the language of choice. There are some languages that can help remove clutter even further by eliminating punctuation. See also: a nice introduction to creating readable DSLs in Groovy.

  1. in Lua here, but not limited to Lua in principle
  2. returning a function would suffice in case of one query

A simple github + travis-ci project for quick c++ to lua binding tests

It’s sometimes necessary to create a simple example for C++ to Lua bindings on the run. Travis-CI might be of great help in that, while online C++ compilers will not suffice.

Here’s the project and a sample code:

https://github.com/d-led/lua_cpp_tryout

#include <lua.hpp>
#include <LuaBridge.h>
#include <RefCountedPtr.h>
#include <LuaState.h>
#include <iostream>

void luabridge_bind(lua_State* L) {
	class Test {
	public:
		Test() {
			std::cout<<__FUNCTION__<<std::endl;
		}

		~Test() {
			std::cout<<__FUNCTION__<<std::endl;
		}
	};

	luabridge::getGlobalNamespace(L)
		.beginClass<Test>("Test")
			.addConstructor<void(*)(),RefCountedPtr<Test>>()
		.endClass()
	;
}

int main() {
    lua::State state;
    luabridge_bind(state.getState());
    try {
    	state.doString("Test()");
    	state.doString("blabla()");
    } catch (std::exception& e) {
    	std::cerr<<e.what()<<std::endl;
    }
}

Test
[string "blabla()"]:1: attempt to call global 'blabla' (a nil value)
~Test

note the automatic lifetime management

In the process of searching for a quick header-only wrapper for the Lua state I came across LuaState which was the first one that compiled out of the box. Its advantage over other wrappers for my needs was that it did reveal the actual Lua state, with the effect of other binding libraries being usable. It could itself provide an alternative to LuaBridge for writing bindings and could be investigated further.

It’s now easy to fork the project and try out bindings online.

Beginning another quest – scripting business logic in .NET: using dynamiclua

Let’s start with Lua

The current state of things is that the lightweight but mighty Lua has become ubiquitous in the world of computing as a scripting and configuration component. Lua’s strategy of “mechanism, not policies” allows the language to be extremely malleable. It’s worth watching Roberto Ierusalimschy’s talks on the evolution of Lua 1.

The latest adoptions of Lua are for example the Redis’ EVAL Query with Lua scripting, and Wikipedia’s template automation using user-written Lua scripts.

dynamiclua

There have been several attempts to bring Lua into the world of .NET, and one of the most recent efforts by Niklas Rother, dynamiclua, combines the previous achievements with the dynamic type of .NET 4.0, and lays path for an easily reusable business logic scripting component, which is now even available via nuget.

After adding dynamiclua as a reference, here’s your first business logic:

using (dynamic lua = new DynamicLua.DynamicLua()) {
 Console.WriteLine(lua("return 2+2"));
}

note the IDisposable usage for freeing native resources.

Discovering the features

Static configuration

As an author of a configurable component,
In order to reduce my support effort,
I want the users of my component to write their static configuration themselves

While for that user story JSON or XML would suffice, we’re on the Lua track, hence this is how it could work:

// comes from some user input or file
string user_static_config = @"
 config = {
  url = 'https://github.com/nrother/dynamiclua'
 }
";

lua(user_static_config);
string url = lua.config.url;
Console.WriteLine(url);

… it does look like JSON, but it isn’t. Here, one can observe the harmony resulting from the use of the dynamic keyword to interact with a dynamic language from a statically typed one. DynamicLua can leverage reflection capabilities of both languages to create an “automagical” interop, compared sometimes tedious writing of bindings for a language, such as native C++.

The power of Lua at the user’s fingertips

As an author of a customizable business software,
In order to reduce my own support effort,
And create a new business of customizations,
I want the administrators of my software to write their business logic scripts themselves

Many systems grow out of static configurability, and business logic definition and evaluation in some programming language becomes inevitable. Whether this is a good thing or a bad one for one’s business 2 is not in the scope of this article, as it is assumed, we want to make our software customizable via scripting 3.

The static configuration entries can be dynamically evaluated at script run time. Various bindings may be used in the script, as i.e. the math standard library here:

lua("config.answer = nil or math.floor(131.94689145078/math.pi)");
int answer = (int)lua.config.answer;
Console.WriteLine(answer);

Using Lua as an expression evaluator

Lua supports multiple return values, which makes certain scenarios fun:

dynamic result = lua("return 1, 'world'");
Console.WriteLine("{0} {1}", result[0], result[1]);

Binding .NET code

Dynamiclua does not have an explicit class binding syntax 4, but it doesn’t matter much, as functions can be bound, and thus, constructors. Via reflection all public 5 members are bound. The domain code is therefore very easy to bind. Take an example:

class Example
{
    int answer = 42;
    public int Answer { get { return answer; } }

    public int Add(int a, int b)
    {
        return a + b;
    }
}

The binding is quite trivial:

lua.NewExample = new Func<Example>(() => new Example());

// Lua functions may be called via dynamiclua
Example my_example = lua.NewExample();
Console.WriteLine(my_example.Answer);

lua(@"
    local example = NewExample()
    print(example.Answer)
    print(example:Add(2,3))
");

Minimal sandboxing

As an author of a scripting component,
In order to mitigate the risk of damage by malicious user-supplied code,
I want the script executing environment to be sandboxed.

Sandboxing is a very complex issue and perhaps only approximations of an undefined ideal sandbox can be made 6. A sane attitude towards this security-related issue should go along the lines of trusting nobody, even oneself, and even that distrust should not be enough. Depending on the posed security requirements, the logic execution component might even be physically separated from your business software, i.e. running on another machine or in another process. But that is perhaps another concern and should be independent of your script execution component.

Since Lua is malleable, one can configure or manipulate the Lua virtual machine to make certain actions unlikely, such as accessing the file system. This can be achieved by setting the bound names to nil as in 7:

lua("import = nil");
lua("require = nil");

new Action(() => lua("import 'System'"))
    .ShouldThrow<Exception>();

In this little spec you can also observe what should happen (non-specifically) if there’s a Lua syntax or a runtime error. You can also see how to import assemblies into the Lua state.

Here’s another quote from the test:

lua.import("System");

Func<int> func = () => (int)lua("return Console.BufferHeight")[0];
new Action(() => func())
    .ShouldNotThrow();
func().Should().Be(Console.BufferHeight);

Without further ado

Some things should perhaps be further investigated:

  • Is dynamiclua prepared for the Mono runtime on *x platforms?
  • Is it possible to crash the process uncontrollably, even while catching exceptions?
  • Fix crash on finalization

Lua can appear simple enough, such that, given a syntactic constraint, even non-programmers could write business logic scripts and configurations. However, there is a company experimenting with alternative ways to define business logic using different approaches to a logic-definition UI. It’s worth checking out: LogicEditor.

Other language and runtime candidates will hopefully be investigated within the next posts of the quest: IronRuby and Boo. The readers of this blog entry are welcome to criticize, point out omitted or wrong information, and interact freely.

Code

https://github.com/d-led/BusinessLogicScripting

  1. Video 1, more slides, Video 2, more Roberto
  2. User scripts are software, and thus might never terminate
  3. I won’t repeat the meme about great power here
  4. as is the case with many C++ bindings i.e. LuaBridge
  5. In my opinion, access to privates should throw…
  6. see wiki: SandBoxes and Daniel Silverstone’s talk at Lua Workshop 2013 on his approach
  7. More …

lurlutil, a console manipulation library for lua : API documented

The cross-platform Lua wrapper of the console manipulation library rlutil seems to have arrived at a certain milestone:

https://github.com/d-led/lurlutil

The API has been expanded, converging on the original scope of rlutil.

Enjoy:

and much more further console fun for Windows, Linux and MacOS X.

yet quicker start for a c++ project

The simplest way to try out some c++ concepts on your machine is the built-in build support of some ‘smart’ text editors, such as Sublime Text or SciTE. However, if you want to start quickly, but be able to grow the project from that one small seed, you’d probably want to have SCM set up.

To start cross-platform c++ projects I usually use git and premake. For premake I’ve set up a couple of quickstart scripts that implement some code organization conventions I usually follow. That project still requires one to set up a git directory, add a submodule, edit a premake4.lua file, write the first code file. How about automating these tasks as well. Every developer writes own support shell scripts, here’s one: new_cpp.sh that doesn’t do much – just what is described above. Considering, you have copied it somewhere where it’s executable globally, here are the steps:

  1. new_cpp.sh project_name → make the directory, init a git repo, add the premake submodule, the first source file and the premake4 build meta-configuration.
  2. cd project_name
  3. premake4 gmake → generate, makefiles, could be vs*, xcode*, too.
  4. make -C Build → build to see if everything is set up.

You can now start growing your code from project_name.cpp.

Quickstart for cross-platform c++ projects

A typical dilemma for a c++ developer is creating the initial build configuration. Out of my affection for Lua, I’ve collected my typical premake4 patterns into a separate project to be able to set up c++ projects on any platform within a minute.

Here’s a sample from selfdestructing:

want to try out cucumber with c++? try cucumber-cpp+premake

feedback and contributions are welcome.

Current status: build needs some cleanup, but it works: travis-ci badge

To build, either use the generated makefiles or the Visual Studio 2012 solution in the Build directory, or clone and extend the premake script.