Higher Debug/Sandboxing Level & setfenv
#1
Posted 14 April 2013 - 03:09 AM
#2
Posted 14 April 2013 - 04:22 AM
#3
Posted 14 April 2013 - 04:23 AM
local x, y, = _G["term"]["getSize"]()
Of course, there is no real reason to use _G when access global variables as it is much simpler to write:
local x,y = term.getSize()
Now setfenv, and its partner function getfenv, are functions that give us a high level of control over the _G table. In fact, if I use setfenv and set the environment to an empty table, the _G table disappears from the scope of the currently running function. For example:
local function brokenFunction()
setfenv(1, {}) --The '1' describes the level at which we are manipulating the environment: 1 is for the current function, 2 is for the calling function
print("lol")
end
brokenFunction()
When you run this function, it will error and give you an "attempt to call nil on line 3" due to the fact that the print function, which is usually stored in our global table, is no longer visible. Of course, we can populate the environment with a few of our own functions if we want to:
local function workingFunction()
setfenv(1, {print = print, globals = _G})
print("_G exists in the form of the 'globals' table now. Watch.")
globals.print(globals.type( {} )) --Ima output 'table'
end
workingFunction()
As you might be able to imagine, this level of control over the global environment can be enormously useful when sandboxing a program.
Hopefully this will get you started on environments and setfenv. You really should go try to re-read the PIL because it is much more comprehensive.
#4
Posted 14 April 2013 - 01:31 PM
EDIT: getfenv returns the current env?
#5
Posted 14 April 2013 - 03:51 PM
Imque, on 14 April 2013 - 01:31 PM, said:
EDIT: getfenv returns the current env?
getfenv does indeed return the current environment.
Edit: By default env level are you talking about the default env level for getfenv()? If so, then I believe that 1 is indeed the default.
#6
Posted 14 April 2013 - 08:28 PM
Imque, on 14 April 2013 - 01:31 PM, said:
EDIT: getfenv returns the current env?
Think of it just like error()'s level parameter.
#7
Posted 14 April 2013 - 08:38 PM
#8
Posted 15 April 2013 - 09:06 AM
This is a vague description...
#9
Posted 15 April 2013 - 09:17 AM
Imque, on 14 April 2013 - 08:38 PM, said:
You have to use it for every function that shouldn't use the global enviroment.
os.loadAPI / os.run use it for example, but I used it to program object oriented, too. (You could find the program in the programs section
#10
Posted 15 April 2013 - 09:31 AM
JokerRH, on 15 April 2013 - 09:17 AM, said:
Object orientation is much easier to do with metatables than setfenv...
local person = {
mt = {
__index = {
race = "Human";
stature = "Medium";
intelligence = "Medium/High";
}
};
new = function(self, attr)
setmetatable(attr, self.mt)
return attr
end;
}
local bob = person:new({
name = "Bob";
job = "Unemployed";
whatever = "etc. etc.";
})
print("I have successfully created a new person: "..bob.name)
print("He is of the race..": bob.race)
--etc. etc.
#11
Posted 15 April 2013 - 09:41 AM
Bubba, on 15 April 2013 - 09:31 AM, said:
#1 You have to use self (if you forget the : it'll take you a long time debugging)
#2 A table has always the same function enviroment as it's creating function
#3 Extending a table with anotherone isn't that simple as extends(object)
#4 It is always getting unclear
#12
Posted 15 April 2013 - 11:50 AM
JokerRH, on 15 April 2013 - 09:41 AM, said:
Bubba, on 15 April 2013 - 09:31 AM, said:
#1 You have to use self (if you forget the : it'll take you a long time debugging)
#2 A table has always the same function enviroment as it's creating function
#3 Extending a table with anotherone isn't that simple as extends(object)
#4 It is always getting unclear
#13
Posted 15 April 2013 - 02:04 PM
JokerRH, on 15 April 2013 - 09:41 AM, said:
Bubba, on 15 April 2013 - 09:31 AM, said:
#1 You have to use self (if you forget the : it'll take you a long time debugging)
#2 A table has always the same function enviroment as it's creating function
#3 Extending a table with anotherone isn't that simple as extends(object)
#4 It is always getting unclear
1) The way I did it yes. But you can easily create one that does not require you use a colon or self.
local mt = {
__index = {
stuff = "hi";
}
}
local function newPerson(attr)
setmetatable(attr, mt)
return attr
end
bob = newPerson({
height=15;
})
2) That is not a disadvantage unless you want to sandbox the user, which is pointless for the majority of purposes.
3) I'm not sure what you're saying here, but if you are saying that using metatables is harder than using setfenv/getfenv, then IMO you're wrong. Metatables really aren't that difficult. Not to mention they are powerful. You have complete control over how the table works. Using metatables you can control what is done upon creating new values, make the table behave as a function, perform regular comparisons directly with the table, and more. You can't do that through a regular environment.
4) They're not unclear at all unless you make it that way.
#14
Posted 15 April 2013 - 03:07 PM
#15
Posted 15 April 2013 - 03:58 PM
Quote
Wikipedia has a pretty good definition of it, even if some people don't trust that as a source. It's good enough to get basic knowledge.
#16
Posted 16 April 2013 - 09:22 AM
#17
Posted 16 April 2013 - 09:40 AM
JokerRH, on 16 April 2013 - 09:22 AM, said:
(I don't remember what parameters are needed to create these objects)
private JPanel container = new JPanel(); // I think I forgot the LayoutManager or something...
private JLabel myButton = new JButton("Label Text");
container.add(myButton);
container.revalidate();
container.repaint();
Lua:
container = Container:new()
btnSend = Button:new("Button Text")
container:addObject(btnSend)
container:drawAll()
Similarity?
#derailed
#18
Posted 16 April 2013 - 09:45 AM
But I actually got a feeling that we're getting offtopic
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users











