lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]




On 04/03/17 10:10 AM, Petri Häkkinen wrote:
On Mar 4, 2017, at 10:13 AM, Sean Conner <sean@conman.org> wrote:

  I use the OOP syntactic surgar for my userdata to isolate the functions
that work on a particular type to just that type.  For example, my socket
class [1], I have functions that create sockets [2]:
Looks good to me! I'm not saying that OOP is always bad. The original post is about extending the existing ':' notation for a more complex case (composition), and I was trying to point out that there are probably simpler solutions to get things done. In my experience, with OOP it's very easy to over-engineer problems, or get distracted by form at the cost of functionality (been there, done that!).

Also, I'm not polluting the
global namespace, or the socket namespace, with functions that require a
particular userdata to do their job.
Also an API made of free functions doesn't have to be in global namespace. The usual solution of require returning a table of public functions of a module works just fine.

Another advantage of the imperative style:

-- OOP

for i=1,#objs do
  objs[i]:do_something()
end

function myclass:do_something()
  -- code here
end
  Again, if the objs are subtly different there could be different
implementations of do_something().  For instance, the objects could be
sockets, where you have one socket for accepting new connections and several
other sockets that are ongoing connections so the code for do_something()
would be different.

In that case I would usually just make two different functions, or pass two arrays into do_something if it makes sense. Better to know the types of objects you are working with and make program flow explicit.

Petri




But can you do

block_in_world = world:get_block(pos)
if block_in_world.inventory then
  block_in_world:inventory.set_item(1, item)
end

(for a minecraft-like game)

Keep in mind each block in the world may store inventory differently (or even store it elsewhere!), so you can't just assume all inventories will behave the same (that is, you can't use a static function unless you're calling a dynamic function, in which case why not call the dynamic function directly?).

If you look at modern Minecraft mods, you'll see they have methods "getCapability" and "hasCapability". You use them like (note: java code)

TileEntity te = world.getTileEntity(pos);
if (te.hasCapability(CapabilityEnergy.ENERGY)) {
  IEnergyStorage energy = te.getCapability(CapabilityEnergy.ENERGY);
  /* do stuff with energy */
}

(And you could use this to argue for `block_in_world:[capabilities.inventory].set_item(1, item)`, but I digress)

--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.