newlisp object system
Posted: Thu Mar 29, 2007 11:24 pm
I have been porting some code from Python to newlisp during the last few weeks. During this process I have recreated some of the Python libraries. I have also taken a good long look at how I want to mimic the object-oriented functionality of Python. This is what I came up with.
This function does most of the work when it creates a new instance.
I can then use this simple object template when writing a class.
Using this approach is very easy. e.g.
If I want an object to pass itself as a parameter (like self, Me, this, etc. in other languages), I use the _me field that was added when the object was created.
If I want to call a function in the parent class that was overloaded (overwritten) in a child class, I can do something like this
And with all this, I have a very simple and working object system that resembles the object system of many other languages.
There's just one problem I'm having: because contexts don't use ORO, all objects created must be manually deleted. If I don't delete them, I essentially have a memory leak.
I would love to have an object system that uses ORO. I made an attempt at it, where I would serialize objects using the (source) function. Whenever I wanted to interact with the object, I would deserialize it into a temporary context, perform the operations, then re-serialize it, and delete the context. Unfortunately my partial implementation of that approach was so terribly ugly that I couldn't bring myself to finish it.
Does anyone have any thoughts on creating a garbage-collected or ORO object system in newlisp?
This function does most of the work when it creates a new instance.
Code: Select all
;; Create a new instance of a class (i.e. context)
(define (.new ctx)
(local (new-instance class-counter instance-num _me)
; get the class counter
(set 'class-counter (sym "instance~count" ctx))
(unless (eval class-counter)
(set class-counter 0))
(set 'instance-num (inc class-counter))
; create the new instance
(set 'new-instance
(sym (string ctx "~instance~" instance-num) MAIN))
(new ctx new-instance)
(set 'new-instance (eval new-instance))
; add the self _me
(set 'new-instance:_me new-instance)
; call the (new) function if it exists
(if new-instance:new
; pass any args into the new function
(eval (append (list new-instance:new) (args))))
new-instance ; return
)
)
(constant (global '.new))
I can then use this simple object template when writing a class.
Code: Select all
(context '__YOUR_CONTEXT_NAME_HERE__)
; Optional base class(es)
;(new __BASE_CLASS_HERE__) ; Base class
; Constructor and parameters -----------v
(define (__YOUR_CONTEXT_NAME_HERE__:new )
; Your init code here
; e.g. (set 'instance-val "value")
)
(context 'MAIN)
Code: Select all
(load "StringIO.lsp")
(set 'memstream (.new StringIO)) => StringIO~instance~1
(memstream:write "Hello") => 5
(memstream:seek 0) => 0
(memstream:read) => "Hello"
Code: Select all
(some-function _me)
Code: Select all
(context 'MyStringIOChild)
(new StringIO) ; Base class
(define (write str)
; Call the parent function
(local (parent.function)
(def-new 'StringIO:write 'parent.function)
(parent.function str)
)
(println "You wrote " str)
)
(context 'MAIN)
There's just one problem I'm having: because contexts don't use ORO, all objects created must be manually deleted. If I don't delete them, I essentially have a memory leak.
I would love to have an object system that uses ORO. I made an attempt at it, where I would serialize objects using the (source) function. Whenever I wanted to interact with the object, I would deserialize it into a temporary context, perform the operations, then re-serialize it, and delete the context. Unfortunately my partial implementation of that approach was so terribly ugly that I couldn't bring myself to finish it.
Does anyone have any thoughts on creating a garbage-collected or ORO object system in newlisp?