Hello.
Today we will review the implementation of ifTrue:ifFalse:
If you've been attentive and I'm sure you have,
you surely noticed that when I suggested examples for Not,
I said you could implement Not, Or and ifTrue:ifFalse:
But in the solution, I never mentioned ifTrue:ifFalse:
We'll solve this problem now.
In effect, in Pharo, conditions are messages.
Here's an example.
We have a weather class: "Weather isRaining".
This means that if it rains...
If it's true, I'll take my umbrella.
If it's false, I'll take my sunglasses.
With ifTrue:ifFalse:
You see the two colons? This means they're keyword messages.
The message ifTrue:ifFalse: is a keyword message
and it's sent to a boolean instance.
In reality, it is heavily optimized by the compiler and not really sent,
but conceptually speaking it is.
So if you want to redefine the method ifTrue:
ifFalse:
You can do this in Pharo.
I'll explain the technique now.
The ifTrue:ifFalse: method is so important
and we need it to go so fast,
that the function is not actually invoked.
The compiler makes jumps inline instead.
But for the purpose of this class, we'll see how it functions.
I want you to propose an implementation.
You know about blocks.
You know what we did with True and False,
and with Or and Not.
You can do it with ifTrue:ifFalse:
In sum, if my receiver is false, I return 5.
And if my receiver is true, I return 3.
Once again, we have objects, messages and blocks.
It's a bit repetitive, but that's the way it is.
You remember that brackets...
freeze the execution
of the expression they contain,
and that "value" kicks the execution of a frozen code.
With this, and Not and Or,
you should be able to implement your conditions.
Likewise, you should be able to implement ifTrue:ifFalse:
I'll give you a few seconds to think.
How is it implemented?
In exactly the same manner as Or and Not.
In the True class, I have a method called
ifTrue: ifFalse: and two arguments.
One block for True and one block for False.
What do I do?
When I'm in the True block, I execute True.
And when I'm in the False class,
I have the same method with the same two arguments,
but since I'm in the False class, I execute the False block.
I have the booleans' implementation.
How does it work?
Like this.
When I send a message to my boolean,
which is in fact True,
I send ifTrue: do something True or do something False.
Then I look up ifTrue:ifFalse: in the True class,
It's right here.
It says to execute the True block, so I do.
Now I send the message "B is a boolean: False."
I send the message and look here. I find ifTrue:ifFalse:
It says to execute the False block, and that's what I do.
You cannot test this by putting a breakpoint in ifTrue:ifFalse:
It's optimized and the system won't accept it.
But what I do suggest you try, is implement in the same manner:
ifFalse: or ifTrue:
ifTrue: a Block 1,
and ifFalse: A Block 2. Then implement them.
Use a breakpoint and experiment.
So what have we shown with this example?
We saw that sending a message selects the right method.
Here we decided to let the receiver decide its behavior.
And we saw that brackets freeze computation,
and that "value" forces the execution of a frozen code.