tags:

views:

40

answers:

3

Someone said you can have (implementation inheritance) with Rebol using get. So I tried:

shape: context [
  x: 0
  y: 0
  draw: func['object][
    probe get object
  ]
]

circle: make shape [
  radius: 10
  draw: get in shape 'draw
]

rectangle: make shape [
  draw: get in shape 'draw
]

I want to pass the object by reference not by value so I pass only the name using 'Object. But then I have to call it like this

circle/draw 'circle

which is rather lame as I need to repeat the name circle twice while in usual inheritance there is the this keyword which avoid this kind of unatural syntax. Is there a more elegant way ?

Thanks.

+1  A: 

There is a self word. At the risk of creating a false sense of certainty about that, I'll give you an example that presumably does what you want:

shape: make object! [
    x: 0
    y: 0
    draw: func [object [object!]] [
        probe object
    ]
]

circle: make shape [
    radius: 10
    draw: func [] [
        shape/draw self
    ]
] 

rectangle: make shape [
    draw: func [] [
        shape/draw self
    ]
]

Here we've made functions that take zero arguments by calling the base class function with the appropriate "self"

Beware: like other words, it gets bound...and the binding sticks. This can get tricky once you start working with abstractions...

selfWordAlias: func [] [
    return 'self
]

triangle: make shape [
    draw: func [] [
        shape/draw get selfWordAlias
    ]
]

Calling triangle/draw will probably surprise you. You're in the object method and selfWordAlias returns the word "self". But the notion of self was captured and bound at the time the selfWordAlias was defined, which was in the global system context. So that's what you get back.

There are tools for dealing with this, but make sure you've got a firm grip on Scoping in Rebol !

Hostile Fork
Will think about it, it's some time I have disconnected from Rebol just need to come back :)
Rebol Tutorial
+1  A: 

I would have thought that using Rebol's prototypical inheritance is all that you need. It is simpler and more elegant:

shape: make object!
  x: 0           
  y: 0
  draw: func [] [probe self]
]

circle: make shape [
  radius: 10
]

triangle: make shape []

Which give the following results:

>> shape/draw
make object! [
    x: 0
    y: 0
    draw: func [][probe self]
]
>> circle/draw            
make object! [
    x: 0
    y: 0
    draw: func [][probe self]
    radius: 10
]
>> triangle/draw          
make object! [
    x: 0
    y: 0
    draw: func [][probe self]
]
Peter W A Wood
Yes I know about Prototypical inheritance. But it duplicates the draw function. The very point is not to duplicate but share it so that if you change the shared function it's automatically changed everywhere.
Rebol Tutorial
+1  A: 

I use this method when I want to use same function (not the copies of function) for all my objects. Point the function whenever you create an object, even if you copy another object.

>> f: does [print "hello"]
>> o: context [a: 1 b: :f]
>> o/b
hello
>> p: context [a: 2 b: :f]
>> p/b
hello

>> same? get in o 'b get in p 'b
== true ;they are exactly the same function

>> append last second :f " world!" ;change the function
== "hello world!"
>> o/b
hello world!
>> p/b
hello world!

Ofcourse you should take care about the binding issues. Hope this will help.

endo64