uuid: - value: 94d78d4d-fcd1-4d1a-a0fc-e6f8c39d084b langcode: - value: en type: - target_id: daily_email target_type: node_type target_uuid: 8bde1f2f-eef9-4f2d-ae9c-96921f8193d7 revision_timestamp: - value: '2025-05-11T09:00:32+00:00' revision_uid: - target_type: user target_uuid: b8966985-d4b2-42a7-a319-2e94ccfbb849 revision_log: { } status: - value: true uid: - target_type: user target_uuid: b8966985-d4b2-42a7-a319-2e94ccfbb849 title: - value: | Don't use "else" created: - value: '2023-09-11T00:00:00+00:00' changed: - value: '2025-05-11T09:00:32+00:00' promote: - value: false sticky: - value: false default_langcode: - value: true revision_translation_affected: - value: true path: - alias: /daily/2023/09/11/dont-use-else langcode: en body: - value: |
A popular approach to writing clean code is to avoid the "else" keyword and, if possible, avoid nesting if
statements within other if
statements.
If I look at some code, I want to see as few indentation levels as possible, making the code easier to read and understand.
Instead, you check for a condition; if that isn't met, you return early. For example, here is some code I saw recently during a meetup talk:
$callingClass = $scope->getClassReflection()->getName();
if ($callingClass === TextMessageQueueProcessor::class) {
return [];
}
$type = $scope->getType($node->var);
foreach ($type->getReferencedClasses() as $targetClass) {
if ($targetClass === TextMessageSender::class) {
return [
RuleErrorBuilder::message(
sprintf(
"Can not call %s from %s",
$targetClass,
$callingClass
)
)->build()
];
}
}
return [];
There are no else
statements.
If the calling class isn't of the required type, it returns immediately with no violations, and we continue, knowing the calling class must be what we need.
If the target class is one where the code shouldn't be called from, it returns immediately with the violation.
Finally, if no violations were found within the referenced classes, it returns an empty array.
The code always returns an array of rule violations but does so as soon as possible at each point.
The code is clean and readable, and I can understand it, knowing once each condition is passed, I don't need to continue thinking about it.
Whilst there are some situations to use else
, most of the time I've found that I can use an early return instead.
A popular approach to writing clean code is to avoid the "else" keyword and, if possible, avoid nesting if
statements within other if
statements.
If I look at some code, I want to see as few indentation levels as possible, making the code easier to read and understand.
Instead, you check for a condition; if that isn't met, you return early. For example, here is some code I saw recently during a meetup talk:
$callingClass = $scope->getClassReflection()->getName();
if ($callingClass === TextMessageQueueProcessor::class) {
return [];
}
$type = $scope->getType($node->var);
foreach ($type->getReferencedClasses() as $targetClass) {
if ($targetClass === TextMessageSender::class) {
return [
RuleErrorBuilder::message(
sprintf(
"Can not call %s from %s",
$targetClass,
$callingClass
)
)->build()
];
}
}
return [];
There are no else
statements.
If the calling class isn't of the required type, it returns immediately with no violations, and we continue, knowing the calling class must be what we need.
If the target class is one where the code shouldn't be called from, it returns immediately with the violation.
Finally, if no violations were found within the referenced classes, it returns an empty array.
The code always returns an array of rule violations but does so as soon as possible at each point.
The code is clean and readable, and I can understand it, knowing once each condition is passed, I don't need to continue thinking about it.
Whilst there are some situations to use else
, most of the time I've found that I can use an early return instead.