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