Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How to make an objects variables private?

Hey, I'm trying my hand at Object Oriented programming. Compared to java, I'm really having a hard time making the members of an object private, and some functions public.

Here is my code. It is in a ModuleScript

local Pizza = {}

function Pizza.new(...)
	return setmetatable({
		Slices = 8;
		Toppings = {...};
		Cooked = false;
	}, Pizza)
end

Pizza.__index = Pizza

function Pizza:eat(x)
	if x ~= nil then
		self.Slices = self.Slices - x;
	else
		self.Slices = self.Slices - 1;
	end
end

function Pizza:addTopping(x)
	table.insert(self.Toppings, x);
end

Pizza.__newindex = function()
	error("Pizza object is private");
end



return Pizza

And this is what I use to test it

pepperoni = Pizza.new("Pepperoni");
print(pepperoni.Slices);
pepperoni.Slices = 2;
print(pepperoni.Slices);
pepperoni.cheese = 5;

Problem is, setting pepperoni.Slices will indeed change the value of Pepperoni.Slices. How in the world do I make the variable Slices private, so it can't be changed, and my data is protected?

2 comments

0

What do you mean by, 'make an objects' variable private', exactly?

0

often in some coding languages you can declare something private or public. This determines if the public or private item can be used by foreign scripts or objects that are implementing the object. Public gives access, while private does not

2 answers

✓ Accepted answer

The easiest thing to do without having to mess with metatables is to just keep the variables outside of the object. I know this goes against everything you learned about OOP, but it's what works the best in Lua, which isn't OOP. Example:

local Pizza = {}

	function Pizza.new(...)
		local slices = 8
		local toppings = {...}

		local pizza = {}
		
		function pizza:eat(x)
			local originalSlices = slices
			if slices > 0 then
				slices = math.max(0, slices - (x or 1))
			end

			return originalSlices - slices--returns slices eaten
		end

		--[[
			What are you trying to access pizza.slices directly for? That's the exact opposite of what OOP is. In OOP languages, you'll always see x = pizza.GetX() instead of x = pizza.x.
		]]
		function pizza:getSlices()
			return slices
		end

		function pizza:addTopping(toping)
			table.insert(topings, toping)
		end		
		
		return pizza
	end

return Pizza

2 comments

0

It works perfectly! But its really biting me, how does slices and toppings stay around?

0

local variables don't get garbage collected until everything that uses them no longer exists, so as long as pizza exists, those local variables will exist as well.

'local' is the same thing as making a private value in Java.

So

local cake = 10
do
	print(cake)
end

Output:

nil

In Lua values are local to the scope of code that they're in. So creating a value outside of a scope will make it not exist in said scope. If you don't put "local" behind the value name then it is a public value.

In your case, your code should look like this:

do

local Pizza = {}

	function Pizza.new(...)
   	 return setmetatable({
     	   Slices = 8;
    	    Toppings = {...};
   	     Cooked = false;
  	  }, Pizza)
	end

	Pizza.__index = Pizza

	function Pizza:eat(x)
  	  if x ~= nil then
  	      self.Slices = self.Slices - x;
  	  else
    	    self.Slices = self.Slices - 1;
 	   end
	end

	function Pizza:addTopping(x)
	    table.insert(self.Toppings, x);
	end

	Pizza.__newindex = function()
 	   error("Pizza object is private");
	end



	return Pizza

end

----

--This is outside of the scope, it will return a error.
pepperoni = Pizza.new("Pepperoni");
print(pepperoni.Slices);
pepperoni.Slices = 2;
print(pepperoni.Slices);
pepperoni.cheese = 5;

Though your problem is irrelevant: if you want your data to be protected just turn on FilteringEnabled.

4 comments

0

...I'm not sure if this flew past you, but your first example is entirely wrong, and how you edited my code does nothing to make "Slices" private

0

But I get the concept anyways... I was explained it on another site. I guess thanks

1

This doesn't answer the question at all -- Slices is still very much "public".

0

Huh? My bad.

This discussion is preserved as it was. New answers, comments, and votes are closed.