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

LUA [Question] Adding methods to string in CC lua?

Started by jclark, 07 November 2012 - 04:29 PM
jclark #1
Posted 07 November 2012 - 05:29 PM
Help me get my head around something. I found a string splitting function on the lua users' wiki that is defined as an instance method on strings (forgive me if I'm using non-Lua terms here, still picking up the language), i.e., function string:split(). After having issues using it in a turtle program, I extracted it to a standalone file along with a simple test:

Spoiler


function string:split( inSplitPattern, outResults )
  if not outResults then
	outResults = { }
  end
  local theStart = 1
  local theSplitStart, theSplitEnd = string.find( self, inSplitPattern, theStart )
  while theSplitStart do
	table.insert( outResults, string.sub( self, theStart, theSplitStart-1 ) )
	theStart = theSplitEnd + 1
	theSplitStart, theSplitEnd = string.find( self, inSplitPattern, theStart )
  end
  table.insert( outResults, string.sub( self, theStart ) )
  return outResults
end

x = 'foo bar baz'
l = x:split('%s+')
print(l[1])
print(l[2])
print(l[3])

I can run this in the standalone lua interpreter just fine, but it fails in game with 'Attempt to call nil' at the l = x:split('%s+') line. If I change that line to non-method syntax, i.e., l = string.split(x, '%s+') it works in both places. I note that while I can make it work by changing the calling sytax, I didn't have to change the definition; so declaring the the function in method notation is fine (string:split) but calling it that way isn't? Is this just a limitation of CC's lua implementation? Or am I missing a bigger issue here?

TIA,
Jason
Kingdaro #2
Posted 07 November 2012 - 05:41 PM
Well, there are two ways you could go about doing this.

You could go the simple route and call the function with your string as an argument, instead of calling the function on the string itself. (also, replace ":" with ".", because it could cause some potential problems.)

string.split(x, '%s+')

There's also the more complicated, metatable-based route. You could get the string metatable and create the method in it, making strings splittable. (you could even implement the split function using the division operator "/" if you wanted)

local string_mt = getmetatable('')

function string_mt:split(pattern)
  -- your splitting code
end

x = 'foo bar baz'
l = x:split('%s+')

In fact, there's a snippet on the love2d wiki that takes advantage of the metatable method, and even implements the use of the division symbol, among other things.

https://love2d.org/w...ring_extensions
Cloudy #3
Posted 07 November 2012 - 10:47 PM
You cannot alter the string metatable in CC due to the fact that the string metatable is shared between all computers.