initialization of local block variable only at the first time the user call the block

98 Views Asked by At

Is there a way to write a block ( which does not get any parameters) which does something only at the first call.

I want to initialize a local block variable only at the first time and then change its value each time the user call that block by : Block value.

My block will be defined in a method A inside a class B. and the method returns the block.

so each time I call method A it should do the initialization. but every time I call the block it should continue from the same point.

for example: I want i to be initialized to 0.

A
  ^[i:=i+1]


ob1 = B new.
res= obj1 A. 
Transcript show: res value. // should print 1
Transcript show: res value. // should print 2

res2= obj1 A. 
Transcript show: res2 value. // should print 1
2

There are 2 best solutions below

0
On BEST ANSWER

Here's your modified code snippet.

A
   | first |
   first := true.
   ^[first ifTrue: [i := 0. first := false].
     i := i+1]

or more simply:

A
   | i |
   i := 0.
   ^[i := i+1]

Technically the second example initializes the variable before the block is even executed. If that's ok, then this works. If you really want the variable initialized on first call, use the first example.

0
On

You can use the outer context of the block to do that:

MyClass>>myBlock
    | init |
    init := false.
    ^ [init
            ifTrue: [1]
            ifFalse: [
                init := true.
                2]].

This gives different results for the first and the second time the block is accessed:

| block |
block := MyClass new myBlock
{ block value . block value } "=> #( 2 1 )"