This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Fetchetch's profile picture

Overriding Functions

Started by Fetchetch, 14 June 2015 - 12:23 PM
Fetchetch #1
Posted 14 June 2015 - 02:23 PM
Overriding Functions

​So people cant do certain things.


So, remember that time when you were playing on a server and a rule breaker comes and opens up your computer terminal, then types 'shutdown' on your computer when it was doing a important task in multishell? Well this is for you.

Overriding Functions are actually pretty easy.
You can do them in API's where they put there functions in 'non-local' tables.

You can override hello, and foobar here:

test = {
  hello = function() print("Hello World!") end,
  foobar = function() print("Foo Bar!") end,
}

But you cant here:

local test = {
  hello = function() print("Hello World!") end,
  foobar = function() print("Foo Bar!") end,
}

Why? Local is a attribute that will only make that object available to that program/API.
Without it, anything can access it.

Also, if the function is out of a table, you can still access and override it.
Lets say i made a file named test.

function hello()
  print("Hello World!")
end
function foobar()
  print("Foo Bar!")
end
The functions hello and foobar will go under a table named after the file name.
They will still work the same and anyone can access it.

So, you know the basics of functions in tables.

Now lets get to overriding.
So, lets say im creating a file called: "noshutdown".
I want it to say "No." when os.shutdown() is called.
To do that,

function os.shutdown()
  print("No.")
end
Run the program, and when os.shutdown() is called, it would print "No." instead of shutting the computer off.

You can do this for all functions that arent local.

Basically your altering functions until you restart. (unless you have it saved as startup ;)/> )
It is kinda like Open Terminal's OTOS.Hook().

So, like above you can do it for every function that isnt local, meaning people that really want to be a big @!&#% can do this:

function shell.run(...)
  printError("No such program")
end
function os.run(...)
  return nil
end
Mean eh?
Edited on 14 June 2015 - 02:29 PM
Creator #2
Posted 14 June 2015 - 02:59 PM
Well, you said that locals apply to programs, APIs and something else. They actually apply to functions.

When a programs is loaded, the file is read, the resultimg string loaded with loadstring. And then called. (loadfile can also be used)

This is why programs are functions, meaning that waht you said ain't wrong but unprecise.
Fetchetch #3
Posted 14 June 2015 - 04:29 PM
Well, you said that locals apply to programs, APIs and something else. They actually apply to functions.

When a programs is loaded, the file is read, the resultimg string loaded with loadstring. And then called. (loadfile can also be used)

This is why programs are functions, meaning that waht you said ain't wrong but unprecise.

Ok, fixed that.
Creator #4
Posted 14 June 2015 - 07:41 PM
You are welcome ;)/>
cyanisaac #5
Posted 19 June 2015 - 06:52 PM
Uh, just so you know. OTOS.hook() was a mockup of what I was going to do with having addons do stuffs later… It wasn't overriding functions…. Lol.

However a GOOD example of overriding functions from my OS is how it sets os.pullEvent to os.pullEventRaw when the user is getting text input in the core file/shell.

But, anyways, thanks for referencing me :D/> (lol) and thank you for the tutorial as this will help me secure my OS's files :D/>
Edited on 19 June 2015 - 04:57 PM
Fetchetch #6
Posted 02 August 2015 - 04:01 AM
Uh, just so you know. OTOS.hook() was a mockup of what I was going to do with having addons do stuffs later… It wasn't overriding functions…. Lol.

However a GOOD example of overriding functions from my OS is how it sets os.pullEvent to os.pullEventRaw when the user is getting text input in the core file/shell.

But, anyways, thanks for referencing me :D/> (lol) and thank you for the tutorial as this will help me secure my OS's files :D/>
//offtopic: Wow. Im a month and 19 days late :D/>

No problem.
H4X0RZ #7
Posted 11 August 2015 - 09:08 PM
This won't always work. If you have a program like this:

local tbl = {}
tbl.test = function()
	print("This is a test")
  end
}

local meta = {}
meta.__newindex = function(k,v) printError("Nope.") end
meta.__metatable = {"Nope."}

tbl = setmetatable(tbl,meta) --Not sure if you have to set tbl to setmetatable(...) though

_G["tbl"] = tbl
and run it,

you can call tbl.test() and it will print "This is a test" but you cant override it :P/>
Edited on 11 August 2015 - 07:09 PM
SquidDev #8
Posted 11 August 2015 - 09:12 PM
you can call tbl.test() and it will print "This is a test" but you cant override it :P/>
Rawset to the rescue!

rawset(tbl, "test", function() print("Hehehe") end)
ElvishJerricco #9
Posted 12 August 2015 - 03:14 AM
you can call tbl.test() and it will print "This is a test" but you cant override it :P/>
Rawset to the rescue!

rawset(tbl, "test", function() print("Hehehe") end)

Also, the metatable above doesn't even work. __newindex only works with keys that haven't yet been assigned. So you are allowed to do tbl.text = …

You would have to do something like this.


local _tbl = {}
function tbl.test()
end

_G.tbl = setmetatable({}, {__index = _tbl, __newindex = error })
H4X0RZ #10
Posted 12 August 2015 - 05:03 AM
you can call tbl.test() and it will print "This is a test" but you cant override it :P/>/>
Rawset to the rescue!

rawset(tbl, "test", function() print("Hehehe") end)

Also, the metatable above doesn't even work. __newindex only works with keys that haven't yet been assigned. So you are allowed to do tbl.text = …

You would have to do something like this.


local _tbl = {}
function tbl.test()
end

_G.tbl = setmetatable({}, {__index = _tbl, __newindex = error })
Oh, fail. (i fail a lot lately) but you can still not edit the function in the table (without rawset).
SquidDev #11
Posted 12 August 2015 - 07:30 AM
Also, the metatable above doesn't even work. __newindex only works with keys that haven't yet been assigned. So you are allowed to do tbl.text = …

Well, that is useful - I always thought it worked the other way round - shows you how much I use __newindex :)/>.