I am programming in squeak and need to compare two blocks of code as follows: (toRunBlock is an instance variable)
~~~Other code~~~
toRunBlock := [nil].
~~~Other code~~~
But at some point, I need to compare it to another block of code:
(toRunBlock = [nil]) ifTrue: [
"Run some code if toRunBlock hasn't been overwritten"
].
But that check is always giving false, and I can't find a way to check if they're equal. Can someone help me out with this?
As @LeandroCaniglia pointed out, you shouldn't have to compare blocks. Here are two ways to solve your problem without comparing blocks:
initialize the variable to nil
. In your accessor method you initialize it lazily:
toRunBlock
^ toRunBlock ifNil: [ [] ]
Now, when you look at the variable toRunBlock
it will be nil
unless #toRunBlock
has been sent or the block as been set by other means.
Your code would become:
toRunBlock ifNil: [
"Run some code if toRunBlock hasn't been overwritten"
].
use additional state by setting an instance variable you can check. This could be your setter method for example:
toRunBlock: aBlock
toRunBlock := aBlock.
hasToRunBlockBeenSet := true
And to check you could use a method like this:
hasToRunBlockBeenSet
^ hasToRunBlockBeenSet ifNil: [ false ]
Your code would become:
self hasToRunBlockBeenSet ifTrue: [
"Run some code if toRunBlock hasn't been overwritten"
].
The second method is arguably more reliable.
Equality is not defined for BlockClosures, except for reference equality. Although two blocks might behave identically, they are still different because they are closures and not only snippets of code. Each block has a reference to the context (method activation or another block) where it was created in, so your two [nil]
s would at least differ in this regard.
You can only check if the block is still the same as earlier by storing somewhere else what it was earlier. Assuming that [nil]
is some kind of default value in your case, you could store that [nil]
block in another instance variable or a class pool variable (e. g., defaultRunBlock) and compare toRunBlock (by reference) with that variable to check if toRunBlock has been changed.
Object subclass: #YourClass
instanceVariableNames: 'toRunBlock defaultRunBlock'
"or as class variable:"
classVariableNames: 'DefaultRunBlock'
poolDictionaries: ''
category: 'Kernel-Methods'
initialize
defaultRunBlock := [nil]
otherCode
toRunBlock := defaultRunBlock
whereYouCompareThem
toRunBlock == defaultRunBlock ifTrue: [ "..." ]
Or if you wanted to check if toRunBlock changed since the last time when that latter method was called, you could store the previous value in an additional instance variable as well.
whereYouCompareThem
toRunBlock == previousRunBlock ifTrue: [ "..." ].
previousRunBlock := toRunBlock
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With