Objects



An object is a container that groups data and/or functions, usually (always?) assigned to a word (variable) . To access an object's attribute in Red, we use a slash (/) as a separator. This is unusual as most languages use a dot, but once you get used to it, it seems more intuitive as it is similar to a path.

Creating an object:

action! make object! , function! context and  function! object  Red-by-example  

You may use make object! ,  object or context to create an object. They are the same command. object and context are just shortcuts to make object!.

Red []

myobject: object [

       x: 10

       y: 20

       f: function [a b] [a + b]

       name: none

       tel: none

]

myobject/name: "Dimitri"

myobject/tel: #3333-3333

print myobject/x

print myobject/y

print myobject/f 3 5

print myobject/name

print myobject/tel


10

20

8

Dimitri

3333-3333


Evaluation is done only when creating an object! (constructor code). Notice that the print command in the code below is not executed when the object is accessed:

>> myobject: object [print "hello" a: 1 b: 2]
hello
== make object! [
       a: 1
       b: 2
]

>> myobject/a
== 1

Self reference:

When an object must do a reference to itself, we use a special keyword named self :

Red []

myobject: object [

       x: 10

       y: 20

       f: function [a b] [a + b]

       autoanalisys: does [print self]

]


myobject/autoanalisys


x: 10

y: 20

f: func [a b][a + b]

autoanalisys: func [][print self]

Cloning an object:

Simply assigning an object to another creates a "link" to the same data. If the original changes, the second also changes:

>> a: object [x: 10]                ;lines of the console deleted for the sake of clarity.
>> b: a                                ;lines of the console deleted for the sake of clarity.
>> a/x: 20
== 20

>> b/x
== 20                                ;changed too!

To make a true copy of an object, we use the word copy:

>> a: object [x: 10]                ;lines of the console deleted for the sake of clarity.
>> b: copy a                        ;lines of the console deleted for the sake of clarity.
>> a/x: 20
== 20

>> b/x
== 10                                ;NO change! b is a true copy.

Prototyping (Inheritance)

Any object can serve as a prototype for making new objects. If we want to create a new object that inherits the first object , we use: make <original object> <new specifications>:

Red []

a: object [x: 3]

b: make a [y: 12]

print b


x: 3

y: 12




Another example:


Red []

myobject: object [

       name: none

       tel: none

]

myobject/name: "Dimitri"

myobject/tel: #3333-3333


myextended-object: make myobject [

       gender: "male"

       zip_code: 666

]


myextended-object/name: "Igor"

myextended-object/tel: #9996-9669


prin myobject/name prin "  tel:" print myobject/tel

prin myextended-object/name prin "  tel:" prin myextended-object/tel

prin "  gender:" prin myextended-object/gender prin "  zip:"

print myextended-object/zip_code


Dimitri  tel:3333-3333

Igor  tel:9996-9669  gender:male  zip:666

 find and select - for objects

find simply checks if the field exists, returning true or none .

select does the same checking, but if the field exists, returns its value.

Red []

obj: object [a: 44]

print find obj 'a

print select obj 'a

print find obj 'x

print select obj 'something


true

44

none

none


Notice that both look for the word (indicated by the ' symbol preceding it), not the variable itself. The variable would be accessed by a simple path like obj/a.



Note on extending objects:


Documentation says the built-in function extend should be able to add new items not only to map!, but also to object! However, this seems not to have been implemented yet.



< Previous topic                                                                                          Next topic >