metaeducation / rebol-issues

6 stars 1 forks source link

BIND special treatment of :self returns a frame!, not an object! #1537

Closed rebolbot closed 8 years ago

rebolbot commented 14 years ago

Submitted by: BrianH

BIND normally does special treatment of the word self in all its varieties, making it visible. The type of the value assigned to self is normally object!. However, if you reference self using a get-word :self, it returns a frame! instead.

So either self is a frame! internally and just converted to an object!, or BIND isn't doing the :self workaround properly and some frame off of the call stack is referenced instead. Not good either way.

This affects object specs, raw BIND of blocks, and (see #1529) many loop functions.

>> a: context []
== make object! [
]
>> do bind [type? self] a
== object!
>> do bind [type? :self] a
== frame!  ; should be object!
>> do bind [type? get 'self] a
== object!
>> do bind [type? get /self] a
== object!
>> do bind [type? get quote self:] a
== object!

CC - Data [ Version: alpha 97 Type: Bug Platform: All Category: Native Reproduce: Always Fixed-in:none ]

rebolbot commented 14 years ago

Submitted by: BrianH

Note that if you have overridden 'self with APPEND obj 'self, the default value of the new 'self field is unset. This means that using :self to refer to that field is not necessarily as rare as you might think: You would use :self on objects that need to work whether 'self was overriden or not.

rebolbot commented 14 years ago

Submitted by: BrianH

Self is a frame! internally and just evaluated to an object! at runtime. What we call a "context" in REBOL is called a frame! inside R3. So this is not a bug :)

rebolbot commented 14 years ago

Submitted by: Ladislav

It may be dismissed as a bug, but should be documented somewhere, to not work as a "gotcha".

rebolbot commented 14 years ago

Submitted by: meijeru

I am afraid it is still a bug, because the actual frame value yielded is most probably NOT the context frame of the object, but indeed -- as you feared -- same arbitrary frame. Proof: look up the pointer in memory that is the implemented value of the frame! -- you can do this with an extension.

rebolbot commented 14 years ago

Submitted by: meijeru

More helpful information (not adding to the confusion, I hope):

>> type? a: do bind [:self] context []
== frame!
>> type? a
== object!
>> type? :a
== frame!