Return only object words but not functions defined with colon as the suffix

时间:2015-07-28 16:33:06

标签: rebol rebol3

When an object! is created as below:

REBOL []


Room: make object! [
    price: copy ""
    area: copy ""

    total: func [] [
        price * 2
    ]

    set 'total2 func [] [
        price * 3
    ]
]

The result of probe Room is:

make object! [
    price: ""
    area: ""
    total: make function! [[][
        price * 2
    ]]
]

The function total: is printed, but the function total2 is not. I have a script where I saved a map! as a series of repend [hash Room]. Before I added the function total, the Room object would return only the words, like

make object! [
    price: ""
    area: ""
] 

After adding the total function, it is also returned and it modifies the output which is was I want to avoid. So, besides changing total: to set 'total is there a way to return only the prior output?

In the Rebol/Saphir book, there's a /display word or refinement, but it does not seem to work in my system Atronix 3.0.0.4.40:

** Script error: cannot access display in path Room/display

So what to do? Create a map! of price, area and its values?

1 个答案:

答案 0 :(得分:3)

The function total: is printed, but the function total2 is not.

Binding-wise, your total2 is bound to the enclosing context...not the object. So if you were to run that from the console:

>> Room: make object! [
    price: copy ""
    area: copy ""

    total: func [] [
        price * 2
    ]

    set 'total2 func [] [
        price * 3
    ]
]

>> probe :total2
make function! [[][price * 3]]

It sounds like you were doing it in the first place because you were wanting to "hide" the functions from the object's output, yet still have them be there. Generally it's probably not the best idea to probe or debug-dump an object as the way of serializing it if you don't want to see the functions.

On a technical point of the way objects work in Rebol: when you put function member values in an object like this, they really are unique functions. So every one of the objects with a function member has a copy of the body, with its words bound specifically to the identity of words of that object instance. While a bit of a performance puzzle, having each object be fully independent lets each one be customized. But if this is a problem for your purposes, then you would keep your functions outside of the object.

If that's not a problem, you should probably write a serialization function for those cases when having the functions just be in the object is bothering you.

Though it's not what you're looking for in this case, I'll mention something kind of cool... PROTECT/HIDE:

>> Room: make object! [
    price: $1'000'000.99
    area: 20x40

    total: func [] [
        price * 2
    ]

    sneaky: does [total]
]

>> protect/hide 'room/total

>> room
== make object! [
    price: 1000000.99
    area: 20x40
    sneaky: make function! [[][total]]
]

>> room/total
** Script error: cannot access total in path room/total

>> room/sneaky
== 2000001.98

It's a way of removing things from visibility or binding, but any previously existing bindings will still work. And if you use it as the parent object for a MAKE!, the hidden items will still be there:

>> o: make Room [price: $304 area: 10x20]
== make object! [
    price: $304
    area: 10x20
    sneaky: make function! [[][total]]
]

>> o/sneaky
== $608

>> o/total
** Script error: cannot access total in path o/total

>> o/total: does [print "can't overwrite it, either!"]
** Script error: cannot access total in path o/total: