Hard Written By GR1PP3RTV

Global Metatable Functions Created on: 30-12-2019

Raw functions and newproxy.

Warning: Before viewing the tutorial, you need to understand about metatables The functions in this tutorial are Lua Globals , so you can use it on any engine that uses lua. If any code or information is wrong, please send me feedback.

Functions Introduction

Global metatable functions are functions outside of metatable, these functions can change the table without metatatble interrupting. newproxy is a different function that can be used to create resources in the code environment.

Functions:

<userdata> newproxy(bool addMetatable = false)```
Creates a new userdata, using metatable.


rawequal(v1, v2)` Checks if v1 equals v2 , without invoking __eq metamethod.

<variant> rawget(array table, index)```
Gets the value of index from real table, without invoking  __index  metamethod.


table rawset(array table, index, value)` Sets the real value of real table index, without invoking __newindex metamethod (can be used against the ReadOnly method).

If you don't understand, will have some examples below, the examples are well explained for a better understanding.

Functions Examples

First let's make a metatable for the examples, named "Met".

local Met = setmetatable({JohnDoe = 1, ROBLOX = 2, Admin = 3}, {
	__index = function() -- For rawget
		error("Not is possible to call a index")
	end,

	__newindex = function() -- For rawset
		error("Not is possible to create a new index")
	end,

	__eq = function() -- For rawequal
		error("Not is possible to compare the table")
	end

Ok, now you think, how will I call some index or create and compare the table if it is not possible? Well, so that's why there are these raw functions, to set the table without calling these metamethods.

First, let's call some index by the rawget function, without invoking the __index metamethod.

print(rawget(Met, "JohnDoe")) -- 1
-- Good, now let's see if we can get the index value without using rawget

print(Met.JohnDoe) -- Error: Not is possible to call a index
-- Oh, can't call an index without rawget```

The error that occurred was because invoking the  __index  metamethod, but with  rawget  doesn't invoke this metamethod.
To you understand better, if you use  rawget  on any table with a metatable, it will not invoke this metatable's  __index  metamethod, so the  __index  metamethod function will not be executed.

Now let's create an index on the table, without invoking the  __newindex  metamethod.

rawset(Met, "GR1PP3RTV", 4) -- Not give error

-- Let's try calling the index without rawget print(Met.GR1PP3RTV) -- Error: Not is possible to call a index

-- With rawget print(rawget(Met, "GR1PP3RTV")) -- 4`

You can see that when creating a new index with rawset , it will not give error, like rawget , but without, it would give the error, because it would invoke the __newindex metamethod. Other example:

rawset(Met, "Pizza", 5)
print(Met.Pizza) -- Error: Not is possible to call a index
print(rawget(Met, "Pizza")) -- 5```

The same, so  rawset  would be just like  rawget , but it creates instead of getting.
Now the last function,  rawequal , same as  rawset  and  rawget , but without invoking the  __eq  metamethod.

print(type(Met) == "table") -- Error: Not is possible to compare the table print(rawequal(type(Met), "table")) -- true print(Met == Met) -- Error: Not is possible to compare the table print(rawequal(Met, Met)) -- true`

As you can see, an equal operator can invoke the __eq metamethod, rawequal is different, it does not invoke the metamethod, just like the other functions. It is very easy to understand, if you did not understand, read again.

Now finnaly let's go to newproxy , this function is not used for metatable. The function creates a new userdata, the same as creating a Roblox Service with a metatable setting.

Let's create a new lua global with newproxy .

local toString = setmetatable(newproxy(true), {
	__newindex = function()
		error("toString is read-only")
	end,

	__call = function(table, ...)
		local arguments = {...}
		local string = arguments[1]
		arguments[1] = nil

		return tostring(arguments[1], unpack(arguments))
	end
})
-- Created a new lua global called "toString", replacing tostring

-- Using the toString:
print(type(toString(15))) -- string```

Very simple. It would basically be a table, but it's a userdata, being able to create new unofficial services, or replacing.

#Ending
All functions are taken from the Roblox Developer Hub, this tutorial will be updated if update any functions mentioned or add more informationFunctions:

newproxy(bool addMetatable = false)` Creates a new userdata, using metatable.

<variant> rawequal(Variant v1, Variant v2)```
Checks if  v1  equals  v2 , without invoking  __eq  metamethod.


Variant rawget(array t, Variant index)` Gets the value of index from real table, without invoking __index metamethod.

table rawset(array t, Variant index, Variant value)```
Sets the real value of real table index, without invoking  __newindex  metamethod (can be used against the ReadOnly method).


If you don't understand, will have some examples below, the examples are well explained for a better understanding.

#Functions Examples
First let's make a metatable for the examples, named *"Met"*.

local Met = setmetatable({JohnDoe = 1, ROBLOX = 2, Admin = 3}, {

__index = function() -- For rawget
	error("Not is possible to call a index")
end,

__newindex = function() -- For rawset
	error("Not is possible to create a new index")
end,

__eq = function() -- For rawequal
	error("Not is possible to compare the table")
end

})`

Ok, now you think, how will I call some index or create and compare the table if it is not possible? Well, so that's why there are these raw functions, to set the table without calling these metamethods.

First, let's call some index by the rawget function, without invoking the __index metamethod.

print(rawget(Met, "JohnDoe")) -- 1
-- Good, now let's see if we can get the index value without using rawget

print(Met.JohnDoe) -- Error: Not is possible to call a index
-- Oh, can't call an index without rawget```

The error that occurred was because invoking the  __index  metamethod, but with  rawget  doesn't invoke this metamethod.
To you understand better, if you use  rawget  on any table with a metatable, it will not invoke this metatable's  __index  metamethod, so the  __index  metamethod function will not be executed.

Now let's create an index on the table, without invoking the  __newindex  metamethod.

rawset(Met, "GR1PP3RTV", 4) -- Not give error

-- Let's try calling the index without rawget print(Met.GR1PP3RTV) -- Error: Not is possible to call a index

-- With rawget print(rawget(Met, "GR1PP3RTV")) -- 4`

You can see that when creating a new index with rawset , it will not give error, like rawget , but without, it would give the error, because it would invoke the __newindex metamethod. Other example:

rawset(Met, "Pizza", 5)
print(Met.Pizza) -- Error: Not is possible to call a index
print(rawget(Met, "Pizza")) -- 5```

The same, so  rawset  would be just like  rawget , but it creates instead of getting.
Now the last function,  rawequal , same as  rawset  and  rawget , but without invoking the  __eq  metamethod.

print(type(Met) == "table") -- Error: Not is possible to compare the table print(rawequal(type(Met), "table")) -- true print(Met == Met) -- Error: Not is possible to compare the table print(rawequal(Met, Met)) -- true`

As you can see, an equal operator can invoke the __eq metamethod, rawequal is different, it does not invoke the metamethod, just like the other functions. It is very easy to understand, if you did not understand, read again.

Now finnaly let's go to newproxy , this function is not used for metatable. The function creates a new userdata, the same as creating a Roblox Service with a metatable setting.

Let's create a new lua global with newproxy .

local toString = setmetatable(newproxy(true), {
	__newindex = function()
		error("toString is read-only")
	end,

	__call = function(table, ...)
		local arguments = {...}
		local string = arguments[1]
		arguments[1] = nil

		return tostring(arguments[1], unpack(arguments))
	end
})
-- Created a new lua global called "toString", replacing tostring

-- Using the toString:
print(type(toString(15))) -- string```

Very simple. It would basically be a table, but it's a userdata, being able to create new unofficial services, or replacing.

#Ending
All functions are taken from the Roblox Developer Hub, this tutorial will be updated if update any functions mentioned or add more information.

Hard Written By GR1PP3RTV

See GR1PP3RTV's profile on Roblox

Discussion