Q:

When using Metatables with Lua, is there a way for me to determine if the value is being set or being retrieved?

I've set up a "psuedo-oop" system inside of my script that lets me better interact with the UserData from my application.  My system works remarkably good except that it doesn't pass references, it passes values.  Because of this, if I say something like:
World.Body.Parent=World.Body2
Nothing actually happens because it never actually sets the Bodys parent to the other body.  Instead, it kind of simplifies to this:
World=World.Body2
(Because World is the parent of the Body so it is returned).  Now, if I do something like this, on the other hand:
print(World.Body.Parent.Type)
==> World
Because it correctly got the World object (being the parent of the Body).
Now with this all in mind, is there some way to make sure it is passed more by reference instead of actually sending the object?  Any ideas would be appreciated!
Here is the relevant source code that I'm using:
local target=_G

function AddService(service)
    Blank=(function(...) return end)
    CreateTemporaryIndex=(function(obj)
        local env_meta={
            __index=(function(this, key)
                if obj[key]~=nil and obj[key]~=key then
                    if type(obj[key]) ~= "userdata" then
                        return obj[key]
                    else
                        local r,i=pcall(function() Blank(obj[key].Type) end)
                        if r then
                            return CreateTemporaryIndex(obj[key])
                        else
                            return (function(...) local arg={...} table.remove(arg,1) return obj[key](obj,unpack(arg)) end)
                        end
                    end
                else
                    local ofObj=obj:Child(key)
                    if ofObj~=nil then
                        return CreateTemporaryIndex(ofObj)
                    end
                end
                return nil
            end)
        }
        local nRe={}
        setmetatable(nRe,env_meta)
        return nRe
    end)
    target[service.Name]=CreateTemporaryIndex(service)
end

AddService(__Environment.World)
AddService(__Environment.Players)
AddService(__Environment.Lighting)
AddService(__Environment.Environment)

A:

The __index metamethod is only called when accessing properties. In order to implement a custom setter you will need to define the __newindex metamethod as well. You can find more info in the section of the Lua manual that I linked to.
That said, if I were you I would think again whether all of this proxy table complication is really needed. For an example of one of the little corner cases that you might have not covered, iterating over your environments with pairs and ipairs will fail unless you add __ipairs and __pairs metamethods as well.

