Skip to content

Instantly share code, notes, and snippets.

@bil-bas
Created September 17, 2012 15:45
Show Gist options
  • Save bil-bas/1af8def6bebecda7e1ee to your computer and use it in GitHub Desktop.
Save bil-bas/1af8def6bebecda7e1ee to your computer and use it in GitHub Desktop.
Rubyfication of Lua (from my very old DOW2 mod)
import("spon/Object.scar")
-- Arrays
Array = Object:new()
--? @shortdesc Push an element onto the end of the Array.
function Array:push(value)
return table.insert(self, value)
end
--? @shortdesc Pop an element off the end of the Array.
function Array:pop()
return table.remove(self, #self)
end
--? @shortdesc Unshift an element onto the start of the Array.
function Array:unshift(value)
return table.insert(self, 1, value)
end
--? @shortdesc Shift an element off the start of the Array.
function Array:shift()
return table.remove(self, 1)
end
--? @shortdesc Delete element at a position
function Array:deleteAt(index)
return table.remove(self, index)
end
--? @shortdesc Delete all elements of a certain value.
function Array:delete(value)
for i = #self, 1, -1 do
if self[i] == value then
table.remove(self, i)
end
end
return value
end
--? @shortdesc Finds index of an element within the Array.
function Array:find(value)
for i, element in ipairs(self) do
if element == value then
return i
end
end
return nil
end
--? @shortdesc Sort contents of the array
-- function Array:sort(comparison)
-- local function compareValues(a, b)
-- return comparison(a[2], b[2])
-- end
-- return table.sort(self, compareValues)
-- end
--? @shortdesc Filter the values in the Array into a new array, passing them through a mapping function.
--?
--? To add 1 to every existing value in the array (returning a new array):
--? myArray:map(function(v) return v + 1 end)
function Array:map(func)
newArray = self:getClass():new()
for i = 1, #self do
newArray[i] = func(self[i])
end
return newArray
end
--? Array:collect() is an alias for Array:map()
Array.collect = Array.map
--? @shortdesc Iterate through the values in the Array, keeping a running state and injecting an initial value.
--?
--? To sum all the values in an array:
--? myArray:inject(0, function(total, element) return total + element end)
function Array:inject(initial, func)
local state = initial
for i = 1, #self do
state = func(state, self[i])
end
end
--? @shortdesc Does the array include a certain value?
-- TODO: This is astoundingly inefficient. Must be a "has_value" method for tables?
function Array:include(value)
return self:find(value) ~= nil
end
--? @shortdesc First element in the Array
function Array:first()
return self[1]
end
--? @shortdesc Last element in the Array
function Array:last()
return self[#self]
end
--? @shortdesc Iterate through each value.
--? @example for value in myArray:each() do print(value) end
function Array:each()
local i = 0
local function iterator(self)
i = i + 1
return self[i]
end
return iterator, self
end
function Array:concat(other)
for value in other:each() do
table.insert(self, value)
end
return self
end
--? @shortdesc Allow addition of another array to this one.
function Array:append(other)
assert(self:getClass() == other:getClass())
for value in other:each() do
table.insert(self, value)
end
return new
end
--? @shortdesc Allow addition of Arrays (just appending).
function Array.__add(lhs, rhs)
assert(lhs:isKindOf(Array))
assert(lhs:getClass() == rhs:getClass())
return lhs:clone():append(rhs)
end
--? @shortdesc Set subtraction of one array from another.
function Array.__sub(lhs, rhs)
assert(lhs:isKindOf(Array))
assert(lhs:getClass() == rhs:getClass())
local new = lhs:clone()
for value in rhs:each() do
table.remove(new, value)
end
return new
end
--? @shortdesc Prevent an Array being used with an unreasonable value.
--? Value of -1 is the last element. -#array is the first element.
function Array:__newindex(index, value)
assert(type(index) == "number", "Array:__newindex - index should be a number.")
-- Negative values count backwards from the end of the array.
if index == 0 then
assert(false, "Array:__newindex - Can't index an Array with 0.")
elseif index < 1 then
index = #self - index + 1
assert(index < 1,
"Array:__newindex - A negative index must be within the bounds of the array.")
end
-- Fill in spaces in the table using nil
if index > #self then
for i = 1, index - #self do
table.insert(self, nil)
end
end
rawset(self, index, value)
return self
end
Object = {}
--? @shortdesc Create a new object.
function Object:new(...)
local object = {}
setmetatable(object, self) -- Tell new object that it is a subclass of this "class".
self.__index = self -- Make this object into a "class" since it now has other objects inherited from it.
object:init(...) -- Tell the object to initialise itself.
return object
end
--? @shortdesc Initialise the object (automatically called from :new() ).
function Object:init()
-- This should be extended by sub-classes.
end
--? @shortdesc What is the parent of the object?
function Object:getClass()
return getmetatable(self)
end
--? @shortdesc Pretty-print out the object.
function Object:p(name)
EOW:p(self, name)
end
--? @shortdesc Shallow copy of the object.
function Object:clone()
local new = self:getClass():new()
for key, value in pairs(self) do
new[key] = value
end
return new
end
--? @shortdesc Can the object trace inheritance from a given class?
function Object:isKindOf(class)
local object = self
while object ~= nil do
parent = object:getClass()
if parent == class then
return true
end
object = parent
end
return false
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment