WEBVTT

00:00:00.600 --> 00:00:01.640 align:middle
Hello, everyone.

00:00:01.800 --> 00:00:04.400 align:middle
Today we're talking about
errors frequently made

00:00:04.560 --> 00:00:08.360 align:middle
by Pharo developers including myself.

00:00:08.520 --> 00:00:12.520 align:middle
We'll see how to find and fix
common mistakes faster.

00:00:13.560 --> 00:00:16.280 align:middle
Here we have a bit of code.

00:00:16.440 --> 00:00:20.000 align:middle
When it's executed, a debugger opens

00:00:21.080 --> 00:00:24.880 align:middle
and tells us that the message
"self" has been sent to an object

00:00:25.040 --> 00:00:27.680 align:middle
and this object doesn't
understand the message "self".

00:00:27.840 --> 00:00:32.400 align:middle
We might say that "self"
isn't a message that's sent very often,

00:00:32.560 --> 00:00:36.120 align:middle
so there's probably a mistake
somewhere in the code.

00:00:36.280 --> 00:00:38.680 align:middle
Taking a little look at it,

00:00:39.840 --> 00:00:41.800 align:middle
we see there's a period missing,

00:00:42.760 --> 00:00:45.800 align:middle
and so the execution
is happening as though

00:00:45.960 --> 00:00:50.360 align:middle
"self" was a message sent
as a result of "DiceHandle new".

00:00:50.520 --> 00:00:53.640 align:middle
Since the DiceHandle class
doesn't have a "self" method,

00:00:53.800 --> 00:00:56.000 align:middle
the debugger opens.

00:00:57.560 --> 00:01:02.240 align:middle
So the solution is to add this period
at the end of the first line.

00:01:03.720 --> 00:01:06.600 align:middle
Another problem we often see

00:01:06.760 --> 00:01:11.920 align:middle
is messages that shouldn't theoretically
be combined that are combined.

00:01:12.080 --> 00:01:16.280 align:middle
So here we have an error saying
that "includes:ifTrue doesn't exist".

00:01:16.440 --> 00:01:19.400 align:middle
"Includes" exists,"ifTrue" exists,
"Includes:IfTrue" doesn't.

00:01:19.560 --> 00:01:21.560 align:middle
Looking closer,

00:01:21.880 --> 00:01:24.720 align:middle
we realise that indeed

00:01:24.880 --> 00:01:27.240 align:middle
the message is being sent
"includes:ifTrue"

00:01:27.720 --> 00:01:32.120 align:middle
to receiver "x" with 2 parameters,
"33" and a block,

00:01:32.320 --> 00:01:34.320 align:middle
and that doesn't work.

00:01:34.480 --> 00:01:36.600 align:middle
When Pharo sees a key word,

00:01:36.760 --> 00:01:39.120 align:middle
it tries to see
all the subsequent key words.

00:01:39.280 --> 00:01:41.880 align:middle
It takes them all
and considers it as one message.

00:01:42.040 --> 00:01:44.160 align:middle
So what's missing here

00:01:44.320 --> 00:01:45.920 align:middle
is a pair of parenthesis to say

00:01:46.080 --> 00:01:49.480 align:middle
that the message "ifTrue" is sent
as a result of "x includes:33".

00:01:50.520 --> 00:01:54.440 align:middle
In the same way,
"assert:includes does not exist",

00:01:54.600 --> 00:01:57.760 align:middle
what we wanted to do was
"assert on the result of includes",

00:01:57.920 --> 00:02:01.440 align:middle
so the parentheses are missing here.

00:02:02.040 --> 00:02:05.680 align:middle
Don't hesitate to put parentheses
when you have

00:02:05.880 --> 00:02:09.280 align:middle
multiple keyword messages
in the same expression,

00:02:09.440 --> 00:02:13.200 align:middle
to delimit them, because Pharo
will try to group keywords together

00:02:13.360 --> 00:02:16.160 align:middle
and consider it to be one message.

00:02:16.400 --> 00:02:18.600 align:middle
In this example,

00:02:19.080 --> 00:02:23.320 align:middle
we want to have a collection
of numbers in Numbers,

00:02:23.480 --> 00:02:27.720 align:middle
and for the moment,
there's only one number there, 35.

00:02:27.880 --> 00:02:33.000 align:middle
However, if we see what's in numbers,
its not a collection, it's the number.

00:02:33.160 --> 00:02:35.840 align:middle
It's the number 35, so there's a problem.

00:02:37.200 --> 00:02:41.240 align:middle
In the same way, in this code,

00:02:41.400 --> 00:02:45.120 align:middle
if I send the message "new"
to the Dice class

00:02:45.280 --> 00:02:47.400 align:middle
I get the number 6

00:02:47.600 --> 00:02:49.200 align:middle
rather than a 6-sided die.

00:02:49.600 --> 00:02:52.200 align:middle
It's the same problem in both examples.

00:02:52.360 --> 00:02:54.360 align:middle
If we look more closely,

00:02:54.520 --> 00:02:57.880 align:middle
adding "yourself" after "add"

00:02:58.040 --> 00:02:59.520 align:middle
will correct the problem. Why?

00:02:59.720 --> 00:03:02.280 align:middle
Because "add" returns its settings.

00:03:03.000 --> 00:03:05.560 align:middle
So "OrderedCollection new add: 35"

00:03:05.720 --> 00:03:07.920 align:middle
returns 35.

00:03:08.080 --> 00:03:12.000 align:middle
If we add the string to "yourself"
we're sure to get the receiver at the end

00:03:12.160 --> 00:03:14.200 align:middle
and Numbers will be
a collection of numbers.

00:03:14.840 --> 00:03:15.960 align:middle
So the solution here

00:03:16.160 --> 00:03:20.640 align:middle
is to add "yourself"
at the end of each message.

00:03:21.560 --> 00:03:22.680 align:middle
Here's another problem.

00:03:22.880 --> 00:03:26.000 align:middle
Here we have a Book class
in "Borrow" method.

00:03:26.160 --> 00:03:29.200 align:middle
When we execute, we get the message

00:03:29.360 --> 00:03:32.040 align:middle
that "nil does not understand ifFalse".

00:03:32.200 --> 00:03:35.960 align:middle
So we send the message
"ifFalse" here to nil.

00:03:36.120 --> 00:03:38.440 align:middle
What does that mean?
It means that in library

00:03:38.600 --> 00:03:41.360 align:middle
at the value nil, which has
the default value of all the variables,

00:03:41.520 --> 00:03:46.360 align:middle
we can say that probably
"inLibrary" has never been initialized.

00:03:46.520 --> 00:03:51.440 align:middle
We have to put a default value
in that variable.

00:03:51.600 --> 00:03:53.960 align:middle
It's pretty easy to correct

00:03:54.120 --> 00:03:56.240 align:middle
by adding the method "initialize",

00:03:56.400 --> 00:04:01.880 align:middle
which from the creation of each
instance of the Book class

00:04:02.040 --> 00:04:04.480 align:middle
will put the value "True"

00:04:04.640 --> 00:04:07.280 align:middle
in the instance variable in Library.

00:04:07.640 --> 00:04:09.680 align:middle
Except that if we execute this code now,

00:04:09.880 --> 00:04:12.280 align:middle
we'll get another error message,

00:04:12.440 --> 00:04:16.800 align:middle
"Class True
does not understand ifFalse".

00:04:17.520 --> 00:04:21.200 align:middle
Where does this come from?
It's because, what we put here,

00:04:21.360 --> 00:04:23.040 align:middle
is a class.

00:04:23.200 --> 00:04:25.400 align:middle
It's not a Boolean, it's a class.

00:04:26.040 --> 00:04:29.360 align:middle
The Boolean is "true" with a small "t".

00:04:30.480 --> 00:04:34.880 align:middle
Classes generally have a capital letter,

00:04:35.040 --> 00:04:37.280 align:middle
so "True" with a capital is a class,

00:04:37.440 --> 00:04:41.240 align:middle
and "true" with a small "t"
is the unique instance of the True class.

00:04:42.000 --> 00:04:43.920 align:middle
Here's another problem.

00:04:44.240 --> 00:04:46.840 align:middle
In the "roll" method
in the Dice class we expect,

00:04:47.000 --> 00:04:49.760 align:middle
when we roll a Dice, to get a number

00:04:49.920 --> 00:04:52.520 align:middle
between 1 and the number
of faces on the die,

00:04:52.680 --> 00:04:56.280 align:middle
except that here,
when we roll the die we get a die

00:04:56.440 --> 00:05:00.200 align:middle
and not the face we landed on.

00:05:01.200 --> 00:05:05.520 align:middle
The method I just showed you
is equivalent to the method below.

00:05:05.800 --> 00:05:10.760 align:middle
This means that by default, a method
that returns nothing returns "self".

00:05:11.680 --> 00:05:15.680 align:middle
This means our "roll" method,
when executed, returns the die

00:05:15.840 --> 00:05:18.360 align:middle
and not the result of sending "roll"...

00:05:20.040 --> 00:05:24.120 align:middle
Not the result of sending "atRandom"
to the "faces" collection.

00:05:24.920 --> 00:05:27.360 align:middle
So the same problem
in a slightly different example.

00:05:27.800 --> 00:05:31.200 align:middle
Here, we're creating a new method,

00:05:31.360 --> 00:05:33.400 align:middle
in the Dice class,

00:05:33.560 --> 00:05:35.080 align:middle
so in Dice class,

00:05:35.240 --> 00:05:39.400 align:middle
we want to make a new method
to create instances in the Dice class,

00:05:39.560 --> 00:05:43.120 align:middle
which initializes by default
the number of faces at zero.

00:05:44.120 --> 00:05:46.880 align:middle
If we send the message "new"
to the Dice class,

00:05:47.040 --> 00:05:49.480 align:middle
what we'll get is the Dice class itself

00:05:49.640 --> 00:05:52.120 align:middle
rather than a new instance
of the Dice class.

00:05:53.040 --> 00:05:54.080 align:middle
So in both cases,

00:05:54.280 --> 00:05:56.760 align:middle
the fact that there's no return
in "return self"

00:05:56.920 --> 00:06:01.240 align:middle
and "self" by default is the receiver,
in the case of a class method

00:06:01.400 --> 00:06:02.760 align:middle
"self" is the class.

00:06:03.200 --> 00:06:04.920 align:middle
To correct these 2 problems,

00:06:05.560 --> 00:06:09.520 align:middle
we just have to add the caret ^
to return to a specific value.

00:06:11.200 --> 00:06:12.160 align:middle
Next problem,

00:06:12.600 --> 00:06:15.480 align:middle
if this code is executed,

00:06:15.640 --> 00:06:20.520 align:middle
the system seems to be frozen
and nothing else happens.

00:06:20.680 --> 00:06:23.360 align:middle
It's impossible to interact with Pharo.

00:06:23.960 --> 00:06:25.120 align:middle
What causes this problem?

00:06:25.440 --> 00:06:29.000 align:middle
It comes from the fact that
we're implementing a new method

00:06:29.160 --> 00:06:31.920 align:middle
in Dice class.

00:06:33.200 --> 00:06:36.280 align:middle
"Self" is Dice

00:06:36.440 --> 00:06:40.960 align:middle
and so "self new"
will call itself recursively.

00:06:41.320 --> 00:06:42.680 align:middle
The intention here

00:06:43.280 --> 00:06:46.640 align:middle
is to use the creation
of instance by default

00:06:46.800 --> 00:06:48.560 align:middle
defined in the Dice superclass,

00:06:48.720 --> 00:06:51.400 align:middle
and then add things
in relation to that.

00:06:51.560 --> 00:06:53.920 align:middle
By writing like this,
we have an infinite loop,

00:06:54.640 --> 00:06:57.680 align:middle
so we need to replace
"self" with "super"

00:06:57.840 --> 00:07:01.720 align:middle
to request the implementation
of the superclass.

00:07:03.000 --> 00:07:04.880 align:middle
What you should know,

00:07:06.520 --> 00:07:08.360 align:middle
we all make lots of mistakes.

00:07:08.520 --> 00:07:11.600 align:middle
The ones I've shown you
are very frequently made

00:07:11.760 --> 00:07:13.800 align:middle
by all Pharo developers,

00:07:13.960 --> 00:07:17.880 align:middle
so there are things we find
very frequently:

00:07:18.040 --> 00:07:20.360 align:middle
missing periods,

00:07:20.520 --> 00:07:22.240 align:middle
parentheses,

00:07:22.400 --> 00:07:24.480 align:middle
missing carets ^,

00:07:24.640 --> 00:07:26.160 align:middle
and "yourself".

00:07:26.840 --> 00:07:29.800 align:middle
Try to use the debugger
as much as you can to find

00:07:30.000 --> 00:07:33.280 align:middle
the root of problems.
It will really help you.

00:07:33.440 --> 00:07:36.040 align:middle
Don't close it as soon as it opens.

00:07:36.200 --> 00:07:39.520 align:middle
You'll be missing out
on a way to fix problems.

