generic image
Processing...
  • Games
  • Catalog
  • Develop
  • Robux
  • Search in Players
  • Search in Games
  • Search in Catalog
  • Search in Groups
  • Search in Library
  • Log In
  • Sign Up
  • Games
  • Catalog
  • Develop
  • Robux
   
ROBLOX Forum » Game Creation and Development » Scripters
Home Search
 

Re: Magic Metatables - Intuitive Iteration

Previous Thread :: Next Thread 
NXTBoy is not online. NXTBoy
Joined: 25 Aug 2008
Total Posts: 4533
01 Nov 2011 12:08 PM
Here's a neat code snippet:

    function array(t)
        return setmetatable(t, {
            __call = function(self, _, key)
                return next(self, key)
            end
        })
    end

And here's how you use it:

    local t = array {1, 3, 3, 7}
    
    for k, v in t do
        print(k, v)
    end

Look ma, no `pairs`!
Report Abuse
Radioaktiivinen is not online. Radioaktiivinen
Joined: 25 Apr 2009
Total Posts: 18629
01 Nov 2011 12:11 PM
Thats too complex, it belongs to some other subforum.
Report Abuse
NXTBoy is not online. NXTBoy
Joined: 25 Aug 2008
Total Posts: 4533
01 Nov 2011 12:15 PM
For reasons which are much more complex, it's not possible to allow the following in a threadsafe way:

    for v in t do
        print(v)
    end

The issue is that lua passes the first variable (the key) of one iteration to the next iteration, allowing me to use `next`. Without `next`, I need to somehow store the iterator state somewhere - unfortunately, there is nowhere I can store it specific to that loop.
Report Abuse
Radioaktiivinen is not online. Radioaktiivinen
Joined: 25 Apr 2009
Total Posts: 18629
01 Nov 2011 12:45 PM
what exactly does "pairs()" return?
Report Abuse
NXTBoy is not online. NXTBoy
Joined: 25 Aug 2008
Total Posts: 4533
01 Nov 2011 12:47 PM
I think pairs returns `next, t, nil`
Report Abuse
Radioaktiivinen is not online. Radioaktiivinen
Joined: 25 Apr 2009
Total Posts: 18629
01 Nov 2011 12:48 PM
I disliek for loops theyre too complex.

Is the pairs function called each time to for loop loops or wat?
Report Abuse
NXTBoy is not online. NXTBoy
Joined: 25 Aug 2008
Total Posts: 4533
01 Nov 2011 03:01 PM
No, the `pairs` function is only called once. The function returned by the pairs function is called multiple times.
Report Abuse
mew903 is not online. mew903
Joined: 03 Aug 2008
Total Posts: 22071
01 Nov 2011 03:54 PM
pairs() returns everything in a table one at a time.
Report Abuse
NXTBoy is not online. NXTBoy
Joined: 25 Aug 2008
Total Posts: 4533
01 Nov 2011 03:55 PM
@mew: No it doesn't. Trust me - I wrote the code at the top.
Report Abuse
SDuke524 is not online. SDuke524
Joined: 29 Jul 2008
Total Posts: 6267
01 Nov 2011 04:06 PM
NXTboy is correct, it returns next, array, nil.
Report Abuse
mew903 is not online. mew903
Joined: 03 Aug 2008
Total Posts: 22071
01 Nov 2011 04:06 PM
idk :c

returns a number, then a value
Report Abuse
mew903 is not online. mew903
Joined: 03 Aug 2008
Total Posts: 22071
01 Nov 2011 04:07 PM
I don't use it that much :l
Report Abuse
NXTBoy is not online. NXTBoy
Joined: 25 Aug 2008
Total Posts: 4533
01 Nov 2011 04:20 PM
You're muddling concepts:

    local theNextFunction, theTable, aNil = pairs(t)

    local number, value = pairs(t)()
Report Abuse
NXTBoy is not online. NXTBoy
Joined: 25 Aug 2008
Total Posts: 4533
02 Nov 2011 04:41 PM
Anyone think this is actually useful? Or is it pure evil?
Report Abuse
XlegoX is not online. XlegoX
Joined: 16 Jun 2008
Total Posts: 14955
02 Nov 2011 05:17 PM
Your implementation is really wasteful by the way, that's exactly the kind of case where you should be using the prototype pattern and creating one metatable and re-using it for all the instances.

There's actually a lot of libraries that do this sort of thing and declare a wrapper for arrays that adds their own library functionality. For instance, NumPy for Python works like this.
Report Abuse
crazypotato4 is not online. crazypotato4
Joined: 22 Feb 2010
Total Posts: 20000
02 Nov 2011 05:21 PM
"local number, value = pairs(t)()"

lua: test2.lua:2: bad argument #1 to '?' (table expected, got no value)

you're forgetting that the for loop calls next with the arguments of 't' and nil.
Report Abuse
NXTBoy is not online. NXTBoy
Joined: 25 Aug 2008
Total Posts: 4533
02 Nov 2011 05:24 PM
I wasn't too sure where I should declare the metatable. This is presumably equivalently bad:

    function array(t)
        local mt = {
            __call = function(self, _, key)
                return next(self, key)
            end
        }
        return setmetatable(t, mt)
    end

Do I need to go to this?

    array = (function(mt)
        return function(t)
            return setmetatable(t, mt)
        end
    end)({
        __call = function(self, _, key)
            return next(self, key)
        end
    })
Report Abuse
XlegoX is not online. XlegoX
Joined: 16 Jun 2008
Total Posts: 14955
02 Nov 2011 05:43 PM
I mean:

do
local MT = {...}
function array(t)
return setmetatable(t, MT)
end
end

So that you only ever construct one global metatable.
Report Abuse
NXTBoy is not online. NXTBoy
Joined: 25 Aug 2008
Total Posts: 4533
02 Nov 2011 06:04 PM
That behaves in the same way as my code. I'm not used to using `do end` to create a closure - javascript has taught be anonymous functions.
Report Abuse
XlegoX is not online. XlegoX
Joined: 16 Jun 2008
Total Posts: 14955
03 Nov 2011 12:58 AM
No, it actually doesn't. In fact, that highlights a key difference between JavaScript and Lua's virtual machines: the way they handle closure creation. Your version will create a new table, containing a new closure, every single time you call the "array" function. We can obviously agree that:

function() return {} end

Creates a new table every time it is executed. And your code is effectively a much more complicated version of this. At the very least you can agree it's creating a new table every time "array" is called.

Now, due to the way Lua closes over stuff, a new closure is also created every single time the function is called. Any time you write "function(...) ... end" in Lua a new closure is created every single time that line of code is passed. That's the opposite of JavaScript where closures are only created once within the scope of the enclosing function.

In JavaScript you would be right... but Lua isn't JavaScript.
Report Abuse
NXTBoy is not online. NXTBoy
Joined: 25 Aug 2008
Total Posts: 4533
03 Nov 2011 03:31 AM
I don't believe it does create a new table every time it is called. Expanding it slightly by assigning the annonymous function to a variable:

    local metatableMaker = function(mt)
        return function(t)
            return setmetatable(t, mt)
        end
    end

    array = metatableMaker({
        __call = function(self, _, key)
            return next(self, key)
        end
    })

I don't believe for a moment that that creates a new metatable every time. And the code I wrote above does the same thing, but uses an anonymous function instead of the named function `metatableMaker`.
Report Abuse
XlegoX is not online. XlegoX
Joined: 16 Jun 2008
Total Posts: 14955
03 Nov 2011 07:24 AM
I missed the last one of the three. The last one does actually work. The first two do not however. My argument does apply to the first two.

At the very least, the last way is not idiomatic Lua to do it that way. The whole reason that you do stuff in that sort way in JavaScript is because of the fact that closures are created.
Report Abuse
Oysi is not online. Oysi
Joined: 06 Jul 2009
Total Posts: 9058
03 Nov 2011 09:13 AM
[ Content Deleted ]
Report Abuse
NecroBumpist is not online. NecroBumpist
Joined: 12 Sep 2010
Total Posts: 4198
03 Nov 2011 06:01 PM
for i, v in next, table, nil do -- note, the 3rd param (`nil`) is a starting place, it begins with nil, and continues with numbers
print("enjoy your function calls when you could just do this instead");
end

Report Abuse
ruralwetfart is not online. ruralwetfart
Joined: 25 Jun 2010
Total Posts: 1883
05 Nov 2011 12:57 PM
Two above..i have another way of simplifying dat
function array(r)
local ms = {
__call = function(self, _, key)
return next(self, key)
end
}
return setmetatable(t, ms)
end

Report Abuse
Previous Thread :: Next Thread 
Page 1 of 1
 
 
ROBLOX Forum » Game Creation and Development » Scripters
   
 
   
  • About Us
  • Jobs
  • Blog
  • Parents
  • Help
  • Terms
  • Privacy

©2017 Roblox Corporation. Roblox, the Roblox logo, Robux, Bloxy, and Powering Imagination are among our registered and unregistered trademarks in the U.S. and other countries.



Progress
Starting Roblox...
Connecting to Players...
R R

Roblox is now loading. Get ready to play!

R R

You're moments away from getting into the game!

Click here for help

Check Remember my choice and click Launch Application in the dialog box above to join games faster in the future!

Gameplay sponsored by:
Loading 0% - Starting game...
Get more with Builders Club! Join Builders Club
Choose Your Avatar
I have an account
generic image