JanetRossini.github.io

Lua, LSL, Blender, Python in Second Life


Project maintained by JanetRossini

Extending the `ll` Library

Nov 3, 2026 • [lua, recipe, testing]


Small experiment for extending ll library on local machine.

I just test-drove a little experiment to allow extending the local copy of ll to add functions that are listed but not implemented in one’s local slua. The sequence below shows that ll.Euler2Rot is not present, shows that we cannot extend ll (because it is read-only, probably a very good idea) but we can shallow copy it and replace ll with the shallow copy, and the shallow copy works, and, finally, that we can add our own functions to the shallow copy:

local __ = require('../inc/expectations')
local P = require('../src/indexed_path')
local euler_to_rot = P.euler_to_rot

__:describe('extend ll', function()
    local saved_ll
    __:setup(function()
        saved_ll = ll
    end)

    __:teardown(function()
        ll = saved_ll
    end)

    __:test('ll does not have Euler2Rot', function()
        local function will_throw()
            ll.Euler2Rot(vector.zero)
        end
        __:expect(will_throw).throws('attempt to call a nil value')
    end)

    __:test('cannot change ll', function()
        local function will_throw()
            ll.Euler2Rot = function(v) end
        end
        __:expect(will_throw).throws('modify a readonly')
    end)

    __:test('can replace ll', function()
        local new_ll = {}
        for k,v in ll do
            new_ll[k] = v
        end
        ll = new_ll -- overwrite the global
        __:expect(ll.ToLower('ABC'), 'still works').is('abc')
    end)

    __:test('and can extend it', function()
        local new_ll = {}
        for k,v in ll do
            new_ll[k] = v
        end
        ll = new_ll -- overwrite the global
        ll.Euler2Rot = euler_to_rot
        __:expect(ll.Euler2Rot(vector.zero)).is(rotation.identity)
    end)
end)

__:execute()

It’s early days for this idea, but it seems to me that one could provide two require files, each named ‘extend_ll.lua’ or something. The one used in one’s production code would be essentially empty. The one used in local development would use the trick above to create a new ll, with all the Linden-provided functions, plus any functions that one’s code needed, but were not (yet?) provided by the Lindens.

In local development, according to what we see above, when we call, say, ll.Euler2Rot, we’d get our local version, while in world we’d get the then-available Linden version.

I’ll write more about this idea as it develops, maybe even release another little tool.

Safe paths!