This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Goof's profile picture

self function usage?

Started by Goof, 23 March 2014 - 08:33 PM
Goof #1
Posted 23 March 2014 - 09:33 PM
Hello

I was wondering how to use the self function / whateveritis, and tried to make a function to save a table.


tbl = {
  save = function( self, path ) -- i know i could just call "self" for tbl or something instead, but i want to learn how this "self" works
	-- body
	local fileHandle = fs.open( path, "w" )
	fileHandle.write(textutils.serialize(self:tbl))
	fileHandle.close()
  end
}

I have no idea if this is going to work… (probably not)

And if you have the time for it, could you explain / give me a link to a tutorial on how to use this?

Thanks in Advance :D/>
Edited on 23 March 2014 - 08:33 PM
Lyqyd #2
Posted 23 March 2014 - 09:35 PM
You'd use just self instead of self:tbl in your serialize call (since self is a reference to tbl, in this case). You'd call the function with tbl:save("path"), which is the same as tbl.save(tbl, "path").
Goof #3
Posted 23 March 2014 - 09:42 PM
EDIT: Hmm wait a minute…
Did i understand this correctly?

tbl = {
  save = function( self, path )
    -- body
    if type(self) ~= "table" then return false end
    local fileHandle = fs.open( path, "w" )
    if not fileHandle then return false end
    fileHandle.write( textutils.serialize( self ) )
    fileHandle.close( )
    return true
  end;
}
local something = {"Hello"}
tbl.save(something,"Hello") -- this works... ofc
something:save("Hello")-- this is returning attempt to call nil?


Oh. Thank you so much!

im gonna look forward to a moment where i can make even more advanced functions/stuffs with this :o/>/>

Thank you for your quick reply!
Edited on 23 March 2014 - 09:01 PM
CometWolf #4
Posted 23 March 2014 - 10:04 PM
The table something does not have the function save, thus you get an attempt to call nil.

something:save("Hello")
is the same as

something.save(something,"Hello")
Goof #5
Posted 23 March 2014 - 10:08 PM
So i cannot save a table like this:

save = function( self, path ) -- this function is now "global" in the program, not in the tbl
  -- body
  if type(self) ~= "table" then return false end
  local fileHandle = fs.open( path, "w" )
  if not fileHandle then return false end
  fileHandle.write( textutils.serialize( self ) )
  fileHandle.close( )
  return true
end
local mytable = {"Hello there"}
mytable:save("Hi")


or do i have to do something different?
Edited on 23 March 2014 - 09:18 PM
Lyqyd #6
Posted 23 March 2014 - 10:29 PM
You're probably looking for metatables. Using your other example, if you had done:


setmetatable(something, {__index = tbl})
something:save("path")

That would work, since something doesn't have a save key, the metatable __index means that it will look for a key in the tbl table, which it will find and use.
Goof #7
Posted 23 March 2014 - 10:32 PM
Ehh…. Im gonna try with metatables then.

Maybe this might be harder than i though at the beginning. ( to make more "advanced" functions like this )

Thanks :D/>/>
Edited on 23 March 2014 - 09:33 PM
CometWolf #8
Posted 23 March 2014 - 10:34 PM
I was typing this up when Lyqyd ninja'd me, so i figured i might aswell post it.

What you're looking for is something usually refered to as object oriented programming. Basically what you do is you setup a table that's used to create other tables of the same type. This is done mainly by using the __index metamethod

local class
class = { --i just like to keep them all in a table called class :P/>
  file = {
    save = function(table,path)
	  --your definition here
    end,
    new = function(table) -- this is used to setup a new file table
	  return setmetatable(
	    table or {},
	    {
		  __index = class.file -- this makes the table check class.file when you attampt to acess a key it does not have indexed.
	    }
	  )
    end
  }
}
local myTable = class.file.new({"Hello there"})
mytable:save()