reflection_thumbnailReflection brings intelligence to language because their programs can do introspection upon themselves. Rebol is a meta-circular language based on its Homoiconicity property.

From Wikipedia:

In computer programming, homoiconicity is a property of some programming languages, in which the primary representation of programs is also a data structure in a primitive type of the language itself, from homo meaning the same and icon meaning representation.

That’s why there’s no need of a complex Reflection API as you can just use rebol standard functions to get the meta-structure of your Objects. This is how.

Let’s create a simple object (see “Rebol is a Prototype-Based OOP Language“):


Object: make Object! [
    a: 1
    printa: func[][print a]
]

We could also build this object from a data block:


Block: [
    a: 1
    printa: func[][print a]
]
Object: make Object! Block

You just have tackled the code-data duality in Rebol. If test in Rebol’s Console:


>> Object/a
== 1
>> Object/printa
1

To get the body block of the Object, you can type


pick to-block mold object 3

which will output in Rebol’s Console:


>> pick to-block mold object 3
== [
    a: 1
    printa: func [] [print a]
]

Now try this:


>> pick pick to-block mold object 3 1
== a:
>> pick pick to-block mold object 3 2
== 1
>> pick pick to-block mold object 3 3
== printa:
>> pick pick to-block mold object 3 4
== func
>> pick pick to-block mold object 3 5
== []
>> pick pick to-block mold object 3 6
== [print a]
>>

A shorter way to get the definition of ‘a and ‘printa is to use the Rebol get in function:


>> probe get in object 'a
1
== 1
>> probe get in object 'printa
func [][print a]
>> probe second get in object 'printa
[print a]
== [print a]
>>

Now what if you want to get the list of Objet members?

Let’s first experiment:


>> pick pick to-block mold object 3 1
== a:
>> type? pick pick to-block mold object 3 1
== set-word!
>> pick pick to-block mold object 3 2
== 1
>> type? pick pick to-block mold object 3 2
== integer!
>> pick pick to-block mold object 3 3
== printa:
>> type? pick pick to-block mold object 3 3
== set-word!
>> pick pick to-block mold object 3 4
== func
>> type? pick pick to-block mold object 3 4
== word!
>> pick pick to-block mold object 3 5
== []
>> type? pick pick to-block mold object 3 5
== block!
>> pick pick to-block mold object 3 6
== [print a]
>> type? pick pick to-block mold object 3 6
== block!
>>

As you can see a: and printa: are of type set-word! so that we can implement our functions:


members: func[Object /local block][
    block: copy []
    foreach element pick to-block mold object 3 [
        if set-word? element [
            append block element
        ]
    ]
    block
]

Test the function:


>> object-members: members object
== [
    a:
    printa:
]
>> length? object-members
== 2
>> object-members/1
== a:
>> object-members/2
== printa:
>>

To learn more see chapter 10 of Rebolcore.

Bookmark and Share