2010-01-04 3 views
1

Кто-то сказал, что вы можете иметь (наследование реализации) с помощью Rebol, используя get. Поэтому я попробовал:Общая функция в Rebol (наследование реализации)

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 
] 

Я хочу передать объект по ссылке не по значению, поэтому я передаю только имя, используя «Объект». Но тогда я должен назвать это как этого

circle/draw 'circle 

, который является довольно хромым, как мне нужно повторить имя круг дважды в то время как в обычном наследовании есть это ключевое слово, которое избежать такого рода unatural синтаксиса. Есть ли более элегантный способ?

Спасибо.

ответ

2

Существует слово self. Рискуя создает ложное чувство уверенности в том, что я дам вам пример, который предположительно делает то, что вы хотите:

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 
    ] 
] 

Здесь мы сделали функцию, которые принимают нулевые аргументы вызова функции базового класса с соответствующим «я»

Опасайтесь: как и другие слова, он привязывается ... и привязывает палки. Это может получить сложно, как только вы начинаете работать с абстракциями ...

selfWordAlias: func [] [ 
    return 'self 
] 

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

triangle/draw Вызов, вероятно, удивит вас. Вы находитесь в методе объекта, а selfWordAlias ​​возвращает слово «self». Но понятие self было зафиксировано и привязано во время определения selfWordAlias, которое было в глобальном системном контексте. Так вот что ты вернешь.

Есть инструменты для борьбы с этим, но убедитесь, что у вас есть крепкое сцепление на Scoping in Rebol!

+0

Подумайте об этом, я некоторое время отключился от Rebol, просто нужно вернуться :) –

1

Я бы подумал, что использование прототипического наследства Rebol - это все, что вам нужно. Это проще и элегантнее:

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

circle: make shape [ 
    radius: 10 
] 

triangle: make shape [] 

которые дают следующие результаты:

>> 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] 
] 
+0

Да, я знаю о прототипическом наследовании. Но он дублирует функцию рисования. Самое главное - не дублировать, а делиться ею, чтобы при изменении общей функции она автоматически менялась везде. –

1

я использую этот метод, когда я хочу использовать ту же функцию (не копии функции) для всех моих объектов. Указывает функцию всякий раз, когда вы создаете объект, даже если вы копируете другой объект.

>> 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! 

Конечно, вы должны позаботиться о проблемах с привязкой. Надеюсь, это поможет.

Смежные вопросы