Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do implemented protected members when using the closure approach to OOP?

Tags:

oop

lua

Right now I am using closures for implementing OOP in Lua. An abridged example follows. My issue happens when trying to implement stronger_heal inside infested_mariner.

--------------------
-- 'mariner module':
--------------------
mariner = {}

-- Global private variables:
local idcounter = 0
local defaultmaxhp = 200
local defaultshield = 10  

function mariner.new ()
   local self = {}

   -- Private variables:  
   local hp = maxhp        

   -- Public methods:

   function self.sethp (newhp)
      hp = math.min (maxhp, newhp)
   end
   function self.gethp ()
      return hp
   end
   function self.setarmorclass (value)
      armorclass = value
      updatearmor ()
   end


   return self
end

-----------------------------
-- 'infested_mariner' module:
-----------------------------

-- Polymorphism sample

infested_mariner = {}

function infested_mariner.bless (self)

   -- New methods:
   function self.strongerheal (value)
     -- how to access hp here?
     hp = hp + value*2  
   end      

   return self
end

function infested_mariner.new ()
   return infested_mariner.bless (mariner.new ())
end

If I place my infested_mariner definition in another .lua file, it won't be able to access the global private variables, or access to the private variables, defined in the base .lua file. How do I have protected members that only infested_mariner can access, and the solution doesn't involve having all the derived classes in the same file as the parent?

Note: I am currently using getters and setters in the child class for now.

like image 940
Extrakun Avatar asked May 26 '13 11:05

Extrakun


2 Answers

This is a limitation of the closure approach. There is no way to access hp from outside the closure.

It's kind of an ideology issue... Some people say protected members brake encapsulation, so they should be avoided: Make all data private and expand the interface if need be (add public functions). People who say that tend to like the closure approach.

If you want to use protected members, I would probably not use the closure approach. A good naming convention is probably the easiest thing.

self.public_thing = "asdf"
self._protected_thing = "asdf"

Sure, the data is actually public, but this approach works pretty well. This is pretty much what Python does. It comes in handy when you want to mess with internals, like for testing.

like image 56
tprk77 Avatar answered Nov 16 '22 20:11

tprk77


In Lua, you can only access local variables in their scope. In order to allow other functions to see your variables you will need to rewrite it so the protected variables are in a table that is accessible by the child class.

One way to do this is by just making public properties in the current class and use a naming convention (like names starting with a underscore) to denote the protected stuff. You probably know this but I have to say that I think this approach is usually much simpler to implement than real protected variables.

If you want real protected variables, you need to separate the table for the public and the protected stuff. One approach is to change the bless function so that it receives both these tables:

function infested_mariner.bless (pub, pro)
   -- New methods:
   function pub.strongerheal (value)
     pro.hp = pro.hp + value*2
   end
   return pub
end

How to set things up so that constructors pass the protected table to each other is left an exercise. If you go this route you probably want to have some function doing it for you so that you don't get a chance to touch the protected table in a day to day basis.

like image 1
hugomg Avatar answered Nov 16 '22 21:11

hugomg