Avoid Yoda conditions in Perl you should
Tags: perl, conditions, warnings, strictures
Published: 2021-12-28 17:04:29

---
title: Avoid Yoda conditions in Perl you should
published: true
date: 2021-12-28 15:00:00 UTC
tags: Perl,conditions,warnings,strictures
canonical_url: https://phoenixtrap.com/2021/12/28/avoid-yoda-conditions-in-perl-you-should/
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4srrz4c6n6g9cqbk54o8.jpeg
---

I remember a brief time in the mid-2000s insisting on so-called [“Yoda conditions”](https://en.wikipedia.org/wiki/Yoda_conditions) in my Perl. I would place constants to the left of [equality comparisons](https://perldoc.perl.org/perlop#Equality-Operators). In case I accidentally typed a single `=` instead of `==`, the compiler would catch it instead of blithely [assigning](https://perldoc.perl.org/perlop#Assignment-Operators) a variable. E.g.:

```perl
if ( $foo == 42 ) { ... } # don’t do this
if ( 42 == $foo ) { ... } # do this
if ( $foo = 42  ) { ... } # to prevent this
```

And because [a foolish consistency is the hobgoblin of little minds](https://www.goodreads.com/quotes/353571), I would even extend this to string and relational comparisons.

```perl
if ( 'bar' eq $foo ) { ... } # weirdo
if ( 42 > $foo )     { ... } # make it stop
```

It looks weird, and it turns out it’s unnecessary as long as you precede your code with `use warnings;`. Perl will then [warn you](https://perldoc.perl.org/perldiag#Found-=-in-conditional,-should-be-==): “`Found = in conditional, should be ==`“. (Sidenote: Perl v5.36, due in mid-2022, is [slated to enable warnings by default](https://metacpan.org/release/ETHER/perl-5.35.3/view/pod/perldelta.pod#Core-Enhancements) if you do `use v5.35;` or above, in addition to the strictness that [was enabled with `use v5.11;`](https://perldoc.perl.org/perl5120delta#Implicit-strictures). Yay for less boilerplate!)

If you want to fatally catch this and many other warnings, use the [strictures module from CPAN](https://metacpan.org/pod/strictures) in your code like this:

```perl
use strictures 2;
```

This will cause your code to throw an [exception](https://phoenixtrap.com/2021/02/22/exceptional-perl-failure-is-an-option/) if it commits many [categories](https://perldoc.perl.org/warnings#Category-Hierarchy) of mistakes. If you’re running in a version control system’s working directory (specifically [Git](https://git-scm.com/), [Subversion](https://subversion.apache.org/), [Mercurial](https://www.mercurial-scm.org/), or [Bazaar](https://bazaar.canonical.com/)), the module also prevents you from using [indirect object syntax](https://perldoc.perl.org/perlobj#Indirect-Object-Syntax), [Perl 4‑style multidimensional arrays](https://perldoc.perl.org/variables/%24;), and [bareword filehandles](https://perldoc.perl.org/functions/open#Assigning-a-filehandle-to-a-bareword).

Getting back to assignments vs. conditionals, there is one case where I’ve found it to be acceptable to use an assignment inside an if statement, and that’s when I need to use the result of a check inside the condition. For example:

```perl
if ( my $foo = some_truthy_function() ) {
    ... # do something further with $foo
}
```

This keeps the scope of `some_truthy_function()`‘s result inside the block so that I don’t pollute the outer scope with a temporary variable. Fortunately, Perl doesn’t warn on this syntax.

---

_Cover image: [Paul VanDerWerf from Brunswick, Maine, USA](https://commons.wikimedia.org/wiki/File:Yoda_(29065553886).jpg), [CC BY 2.0](https://creativecommons.org/licenses/by/2.0), via Wikimedia Commons_