another question about contexts and layouts
[1/2] from: mh983::yahoo::com at: 9-Mar-2002 13:19
I'm noticing come behavior that seems strange to me,
and my brain hurts from thinking about it. Any help
would be greatly appreciated. Does anybody have any
idea why the following happens:
I was playing around with a view/controller idea. The
controller is just a context that I create an object
from, and it knows about it's view. The view is a
context that knows about it's controller and has a
variable that contains it's layout definition.
The problem I'm having is that if I create 2
controllers, the second controller seems to cause the
first controller to point to the second ones view. I
know this is confusing, so lets just get to the code.
See embedded comments.
REBOL []
controller-ctx: [
val: none
myview: context view-ctx
myview/mycontroller: self
show-window: does [
val: 3
view layout myview/layout-ctx
print myview/name
]
]
view-ctx: [
mycontroller: none
name: "unnamed"
print-val: does [
print mycontroller/val
]
layout-ctx: [
button "Print Value" [print ["the value: "
mycontroller/val]]
button "Print Name" [print ["view name: " name]]
]
]
obj1: context controller-ctx
obj1/myview/name: "view1"
obj2: context controller-ctx
obj2/myview/name: "view2"
obj1/show-window
; NOTE: this is obj1 still, we're not using obj2.
; clicking on the Print Name button will print
; "view2" - so our controller, obj1, has
; the wrong view somehow, because of our
; creation of obj2.
; clicking the Print Value button will print "none",
; Since show-windows was never called for obj2,
; the value hasn't been set -- further evidence that
; obj1 has the wrong view object.
[2/2] from: mh983::yahoo::com at: 12-Mar-2002 11:18
solved: another question about contexts and layouts
Woo hoo! I've discovered my problem (I think), and as
usual, it's pretty dumb. The following example is
essentially the same as the first, but removes some
fluff and removes 'layout from the equation.
The problem is that inner-ctx is just a block and is
not turned into an object at the time we call "context
outer-ctx".
Therefore, both obj1 and obj2 refer to the same
inner-ctx block. Since obj2 is created last, the
value bound to 'name in the inner-ctx block will be
Two
, and both obj1 and obj2 will refer to it.
The simple solution is to just include copy/deep for
the inner-ctx.
I have a hard time making sense of this concept and
would appreciate it greatly if someone has a clear
description. Is it that since the series is
identical, REBOL just points all instances to the same
memory location? For instance, in java if you write:
String x = "hello";
String y = "hello";
You are actually pointing to the same String object in
memory. But since Strings are immutable, you don't
get a surprise change to y when you change x.
I'm wondering if it's the same concept in REBOL except
the series is not immutable. Anyway, thanks for
listening. Here's the new example if anyone's
interested:
REBOL[]
outer-ctx: [
name: "unnamed"
myinner: none
inner-ctx: [
emit: does [print ["name is" name]]
]
init: does [
myinner: context inner-ctx
]
]
; create object1 and give it a name
obj1: context outer-ctx
obj1/name: "One"
; create object2 and give it name
obj2: context outer-ctx
obj2/name: "Two"
obj1/init
print obj1/name ; prints "One"
obj1/myinner/emit ; print "Two"