Andrew Martin wrote:
>Michael Jelinek wrote (in refinements thread):
> > I really just want to separate the definition of the method (function
>body) from the object, but I still want the method to be called as part of
>the object. Some of these objects can be saved to a file and reloaded, and I
>want the function "bound" to the latest definition in the program, not what
>the definition was at the time that the object was saved. Also, although I
>can't claim to "know" the internals of REBOL, I don't want multiple copies
>(or worse, definitions) of the function floating around - it's inefficient.
>
>This is the core of the problem. To have one function per "class" of object,
>not one function per instance, for REBOL. This is easily done in C++, not so
>easily in REBOL. I'm sure it can be done with some suitably cunning script.
>
>I'll have to think about it more deeply, after I've done some fiddling.

Why don't you do what other unique-object OOP languages do,
use class factory objects? Like this:

Accounts: make object! [
     total-balance: $0  ; Class variable
     new: func [/init bal [number! money!] /local the-class] [
         the-class: self
         bal: to-money any [bal $0]
         total-balance: total-balance + bal
         make object! [
             class: the-class
             balance: bal
             deposit: func [amount [number! money!]] [
                 class/deposit self amount
             ]
             withdraw: func [amount [number! money!]] [
                 class/withdraw self amount
             ]
             transfer: func [
                 account [object!] amount [number! money!]
             ] [class/transfer self account amount]
             close: func [] [class/close self]
         ]
     ]
     deposit: func [account [object!] amount [number! money!]] [
         account/balance: account/balance + amount
         total-balance: total-balance + amount
         amount
     ]
     withdraw: func [account [object!] amount [number! money!]] [
         account/balance: account/balance - amount
         total-balance: total-balance - amount
         amount
     ]
     transfer: func [
         account [object!] account2 [object!] amount [number! money!]
     ] [
         account/balance: account/balance - amount
         account2/balance: account2/balance + amount
         amount
     ]
     close: func [account [object!]] [
         total-balance: total-balance - account/balance
         account/balance: $0
     ]
]

Although OOP is overkill for this example, this does show a design
pattern that I have found useful for other tasks, such as parsing with
side effects. The XML parser could use this pattern, for example.

The trick that you should realize in REBOL is that OOP, while supported,
is rarely the best approach. The objects in REBOL have context overhead
that make them rather memory-intensive. It's more appropriate to use OOP
when you have a few large objects. Small objects are better represented
with simpler structures like blocks.

Remember, the idea that OOP requires classes is just held by class-based
OOP language people. The OOP community at large is much more flexible,
including OOP languages built around delegation, actors, closures, etc.
REBOL is much better at following the delegation or closure patterns
than it is at classes (you need concurrency to do the actor pattern).

I hope this helps...

Brian Hawley

Reply via email to