This part is for advanced users only. Beginners should really read previous articles (see related articles at the end) before being able to understand this one.
From First Part (that one was very easy), we have defined these two functions:
Class: func['Class Body [block!]][
Type: to-word Class
set Type Make Object! Body
]
new: func[Class [Object!] ][
Make Class []
]
Let’s say we have added the constructor Person (method name) to our Person Class like this:
Class Person [
Person: func[FirstName LastName][
Self/FirstName: FirstName
Self/LastName: LastName
Print Self/FirstName
Print Self/LastName
]
FirstName: ""
LastName: ""
]
We would initialize a class instance John like this:
John: new Person["John" "Doe"]
In Console let’s create this John (as pre-requisite copy and paste the class and new functions above):
John: new Person
Let’s call John’s Constructor (Person method) by Hand:
John/Person "John" "Doe"
Or:
do rejoin ["John" "/" "Person" " " form [{"John"} {"Doe"}]]
To build the parameters, we will iterate through the parameters but for string type we will have to enquote each parameter so that we will get this in our new function:
new: func[Class [Object!] Param-Block [block!]][
Obj: Make Class []
params: ""
foreach param Param-Block [
if string? param [
param: rejoin [{"} param {"}]
]
append params param
append params " "
]
]
To get the Constructor from the Class Parameter, we’ll use this trick (see Reflection):
Constructor: to-word pick pick Class 1 2
To call the constructor on Obj (for instance John), we’ll use the get function to access the method ‘Person in John’s Object or Context:
do get in John 'Person "John" "Doe"
To do this dynamically is more complex because we have to pass an unknown number of variables in params, so the trick is to first compose the instruction in string format with rejoin and finally apply the do function like this:
do rejoin [{do get in Obj to-word constructor} { } params]
So the new function will be:
new: func[Class [Object!] Param-Block [block!]][
Constructor: pick (pick Class 1) 2
Obj: Make Class []
params: copy ""
foreach param Param-Block [
if string? param [
param: rejoin [{"} param {"}]
]
append params param
append params " "
]
do rejoin [{do get in Obj to-word constructor} { } params]
Obj
]
Test:
>> John: new Person ["John" "Doe"]
John
Doe
Check:
>> Probe John
make object! [
Person: func [FirstName LastName][
Self/FirstName: FirstName
Self/LastName: LastName
Print Self/FirstName
Print Self/LastName
]
FirstName: "John"
LastName: "Doe"
]
>>
This version of new function obliges to have one and only one constructor. In a future version, we’ll refine it to also accept 0 or n constructors (Method Overloading support).
If you want to play with the whole code:
Rebol[
Title: "Class-Based OOP Language"
Version: 2
]
Class: func['Class Body [block!]][
Type: to-word Class
set Type Make Object! Body
Protect Type
]
new: func[Class [Object!] Param-Block [block!]][
Constructor: to-word pick pick Class 1 2
Obj: Make Class []
params: copy ""
foreach param Param-Block [
if string? param [
param: rejoin [{"} param {"}]
]
append params param
append params " "
]
do rejoin [{do get in Obj Constructor} { } params]
Obj
]
Note: we have added Protect Type in the class function so as to protect the Class Name.


















Tags: Advanced, OOP, Reflection