Skip to content

Closures

The Closure functions are used to create, identify, and interact with Luau closures.

checkcaller

function checkcaller(): boolean
Returns whether the function currently running was called by Nihon. This is useful for metamethod hooks that behave differently when called by the game.

Example

local refs = {}

refs.__namecall = hookmetamethod(game, "__namecall", function(...)
    local self = ...
    local isRunningOnExecutor = checkcaller()

    if isRunningOnExecutor then
        -- The executor invoked the __namecall method, so this will not affect the
        -- scripts in the game.
        if self == game then
            error("No __namecall on game allowed")
        end
    end

    return refs.__namecall(...)
end)

game:Destroy() --> Error "No __namecall on game allowed"

clonefunction

function clonefunction<T>(func: T): T
Returns a recreated version of func.

Parameters

  • func - The function to recreate.

Example

local function foo()
    print("Hello, world!")
end
local bar = clonefunction(foo)
foo() --> Hello, world!
bar() --> Hello, world!
print(foo == bar) --> false

getcallingscript

function getcallingscript(): BaseScript
Returns the script responsible for the currently running function.

Example

Prevent scripts in PlayerGui from invoking the __namecall hook:

local refs = {}
local bannedScripts = game:GetService("Players").LocalPlayer.PlayerGui

refs.__namecall = hookmetamethod(game, "__namecall", function(...)
    local caller = getcallingscript()

    -- Use '.' notation to call the IsDescendantOf method without invoking
    -- __namecall and causing a recursive loop.
    local isBanned = caller.IsDescendantOf(caller, bannedScripts)

    if isBanned then
        error("Not allowed to invoke __namecall")
    end

    return refs.__namecall(...)
end)


restorefunction

function restorefunction(func: function): ()
If func has been hooked by a prior hookfunction call, restorefunction will return func to it's prior state. This function will error if func has not been hooked.

Parameters

  • func - The function to restore.

Example

function a(num)
    print(num)
end
local old;
old = hookfunction(a, function(num)
    old(num + 1)
end)
old(5) -> 5
a(5) -> 6
restorefunction(a)
a(5) -> 5

isfunctionhooked

function isfunctionhooked(func: function): boolean
Returns true if func has been hooked by a prior hookfunction call.

Parameters

  • func - The function to check.

Example

function a(num)
    print(num)
end
print(isfunctionhooked(a)) --> false
hookfunction(a, function(num) old(num + 1) end)
print(isfunctionhooked(a)) --> true

isnewcclosure

function isnewcclosure(func: function): boolean
Returns true if func is the result of a newcclosure function call.

Parameters

  • func - The function to check.

Example

function a()
    print("Hello World!")
end
print(isnewcclosure(a)) --> false
local b = newcclosure(a)
print(isnewcclosure(b)) --> true

get_wrapped_original

function get_wrapped_original(func: function): function
Returns the wrapped lclosure from func. Errors if func is not a newcclosure.

Parameters

  • func - The newcclosure to get the lclosure from.

Example

function a()
    print("Hello World!")
end
local b = newcclosure(a)
local c = get_wrapped_original(b)
print(a == c) --> true

hookfunction

function hookfunction<T>(func: T, hook: function): T
Replaces func with hook internally, where hook will be invoked in place of func when called. Returns a new function that can be used to access the original definition of func.

Parameters

  • func - The function to hook.
  • hook - The function to redirect calls to.

Example

local function foo()
    print("Hello, world!")
end
local fooRef = hookfunction(foo, function(...)
    print("Hooked!")
end)
foo() --> Hooked!
fooRef() --> Hello, world!

iscclosure

function iscclosure(func: function): boolean
Returns whether func is a closure whose source is written in C.

Parameters

  • func - The function to check.

Example

print(iscclosure(print)) --> true
print(iscclosure(function() end)) --> false

islclosure

function islclosure(func: function): boolean
Returns whether func is a closure whose source is written in Luau.

Parameters

  • func - The function to check.

Example

print(islclosure(print)) --> false
print(islclosure(function() end)) --> true

isexecutorclosure

function isexecutorclosure(func: function): boolean
Returns whether func was created by Nihon.

Parameters

  • func - The function to check.

Example

print(isexecutorclosure(isexecutorclosure)) --> true
print(isexecutorclosure(function() end)) --> true
print(isexecutorclosure(print)) --> false

loadstring

function loadstring(source: string, chunkname: string?): (function?, string?)
Generates a chunk from the given source code. The environment of the returned function is the global environment. If there are no compilation errors, the chunk is returned by itself; otherwise, it returns nil plus the error message. chunkname is used as the chunk name for error messages and debug information. When absent, it defaults to a random string.

Parameters

  • source - The source code to compile. (bytecode is not accepted.)
  • chunkname - Optional name of the chunk.

Example

local func, err = loadstring("print('Hello, world!')")
assert(func, err)() --> Hello, world!
local func, err = loadstring("print('Hello")
assert(func, err)() --> Errors "Malformed string"

newcclosure

function newcclosure<T>(func: T, debugname: string?): T
Returns a C closure that wraps func. The result is functionally identical to func, but identifies as a C closure, and may have different metadata.

Parameters

  • func - The function to wrap.
  • debugname - The debugname assigned to the C closure. No name is assigned if this is not given.

Example

local foo = function() end
local bar = newcclosure(foo)
print(iscclosure(foo)) --> false
print(iscclosure(bar)) --> true