I'm not quite sure how variable scope works in Io. The docs say it has closures, but I don't seem to be able to see idx
from within the next
and prev
methods. Parent visibility is the key premise of closures, so how can they work?
List iterator := method(
idx := 0
itr := Object clone
itr next := method(
idx = idx + 1
return self at(idx)
)
itr prev := method(
idx = idx - 1
return self at(idx)
)
return itr
)
How should this be achieved?
So you're fundamentally misunderstanding how methods and blocks work, but that's ok. Let's go over the basics:
context means a locals object, basically a stack frame. Scope means who will be the "sender" of the block activation when the block/method is invoked. You can access this by the call sender
object inside the context of a method or block.
Now, let's look at your code. It's almost perfect, there's only one thing missing, and it's non-obvious.
Since methods have dynamic scope, their scope
message returns nil. This signifies to the evaluator that whichever object received that message, should be passed in as the sending context. We don't want that behaviour, we want to capture some scope, specifically the locals of the iter
method we've defined. Let's look at a corrected example:
List iterator := method(
idx := 0
itr := Object clone
itr next := method(
idx = idx + 1
at(idx)
) setScope(thisContext)
itr prev := method(
idx = idx - 1
at(idx)
) setScope(thisContext)
itr
)
I've simplified the bodies, but they haven't changed in terms of functionality (apart from a few less message sends). The important thing is the setScope
call passed to the method before assignment to next
/prev
. I could have chose to rewrite this as:
iter prev := block(
idx = idx - 1
at(idx)
) setIsActivatable(true)
but I'd have then had to make the block activatable, since blocks are not activatable by default. The code above, and the corrected itr prev
using method()
are functionally equivalent.
Methods are not closures, blocks are. A block is simply a method whose scope is non-nil, they are the same object.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments