Stack Error

Monkey Forums/Monkey Programming/Stack Error

Leo Santos(Posted 2011) [#1]
Hi,

How do I remove an object from a stack when I don't know its stack index?

Here's an example:

Strict

Function Main:Int()
	
	Local test:= New Stack<obj>
	
	Local bob:= New obj("bob",10) 
	test.Push( bob )
	Local joe:= New obj("joe",20) 
	test.Push( joe )
	Local moe:= New obj("moe",30) 
	test.Push( moe )
	
	For Local temp:obj = Eachin test
		Print temp.name + ", " + temp.x
	Next	
	
	test.RemoveEach( joe )	'<----Error here
	
	For Local temp:obj = Eachin test
		Print temp.name + ", " + temp.x
	Next
	
	Return 0

End

Class obj
	Field x:Int 
	Field name:String
	Method New( name:String, x:Int )
		Self.name = name
		Self.x = x
	End
End


This will cause an error, but it actually works fine if I try a similar thing on a List instead of a Stack. Is there a good reason why it doesn't work with object Stacks? Maybe it's a bug?

Thanks!


muddy_shoes(Posted 2011) [#2]
In the absence of Interfaces in the language collections classes are always going to be less than they might be. If you look at the stack implementation you'll see that the Compare method does nothing but print that error. For whatever reason, the base implementation is practically abstract if not actually declared as such.

You can take the lead from the IntStack, FloatStack and StringStack implementations and create your own "ObjStack" that is specific to your new class:

Class ObjStack Extends Stack<obj>

	Method ToArray:obj[]()
		Local arr:obj[Length]
		Local i:Int
		For Local t:obj = Eachin Self
			arr[i]=t
			i+=1
		Next
		Return arr
	End
	
	Method Compare:Int( lhs:Object,rhs:Object )
		Local lObj:obj = obj(lhs)
		Local rObj:obj = obj(rhs)
		If( lObj.name = rObj.name And lObj.x = rObj.x )
			Return 0
		End
		Return -1
	End
End


...or, if you want a generic ObjectStack that just compares the instance rather than the value, you can do that:

Class ObjectStack Extends Stack<Object>

	Method ToArray:Object[]()
		Local arr:Object[Length]
		Local i:Int
		For Local t:Object = Eachin Self
			arr[i]=t
			i+=1
		Next
		Return arr
	End
	
	Method Compare:Int( lhs:Object,rhs:Object )
		If( lhs = rhs )
			Return 0
		End
		Return -1
	End
End


...with the downside that you will have to cast everything back to your actual object type.


therevills(Posted 2011) [#3]
Have you seen Samah's collection module in Diddy?

http://code.google.com/p/diddy/source/browse/trunk/src/diddy/collections.monkey

You can use the ArrayList like Stack and create your own comparator class so that you sort it:

http://www.monkeycoder.co.nz/Community/post.php?topic=583&post=4862


Leo Santos(Posted 2011) [#4]
That's some great info, thanks Damian!

As far as Diddy, I haven't had time to check it yet, but it seem very interesting. That Collection class even has a Sort method, which I need right now!... :-)

Cheers!
Leo.


Samah(Posted 2011) [#5]
I started making a LinkedList class for it (basically a double-ended queue that you can use like a stack) but polymorphism in Monkey is really blergh and I was having heaps of problems (mostly with EachIn and ObjectEnumerator).

Once I've got a base version of the GUI checked in I might look at LinkedList again.


therevills(Posted 2011) [#6]
I might look at LinkedList again


DONT DO IT!! :P


Brucey(Posted 2011) [#7]
polymorphism in Monkey is really blergh

It's not that bad, is it?