<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Taylor Kearns</title>
    <description>The latest articles on Forem by Taylor Kearns (@taylorkearns).</description>
    <link>https://forem.com/taylorkearns</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F701834%2Fb5d591a6-7f67-4c0b-a687-390bd22d28e1.jpeg</url>
      <title>Forem: Taylor Kearns</title>
      <link>https://forem.com/taylorkearns</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/taylorkearns"/>
    <language>en</language>
    <item>
      <title>Ruby to the Rescue</title>
      <dc:creator>Taylor Kearns</dc:creator>
      <pubDate>Mon, 30 Jan 2023 21:42:09 +0000</pubDate>
      <link>https://forem.com/thegnarco/ruby-to-the-rescue-3ke8</link>
      <guid>https://forem.com/thegnarco/ruby-to-the-rescue-3ke8</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Though we frequently use the terms "throw" and "catch" when discussing error handling, we must be careful in Ruby to use the more accurate terms "raise" and "rescue". "Throw" and "catch" have a significantly different meaning in Ruby. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;The other day we were writing an RSpec test and were surprised to find that we couldn't get this test to pass:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;expect { throw StandardError.new("error") }.to raise_error&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;But we &lt;em&gt;could&lt;/em&gt; get this test to pass:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;expect { raise StandardError.new("error") }.to raise_error&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Aren't these basically the same thing, with a minor syntactic difference? Raise an error, throw an error, same idea right? In Javascript we use &lt;code&gt;try..catch&lt;/code&gt; for handling errors. Isn't it the same idea with Ruby? Not really. Ruby has two similar looking statements: &lt;code&gt;try..catch&lt;/code&gt; and &lt;code&gt;raise..rescue&lt;/code&gt;. Even though we can technically use each of these statements in similar situations and get ostensibly similar results, the intent behind the two structures is quite different.&lt;/p&gt;

&lt;h2&gt;
  
  
  In Ruby, Don't Catch Errors; Rescue Them
&lt;/h2&gt;

&lt;p&gt;The main source of confusion (for me, anyway) is in the term &lt;code&gt;catch&lt;/code&gt;. When I think &lt;code&gt;catch&lt;/code&gt;, I think error. In Javascript if we want to handle an error we write something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;myFunction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`There was an error: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So in Ruby wouldn't I do something similar? Yes, but not with &lt;code&gt;try..catch&lt;/code&gt;. In Ruby we use &lt;code&gt;raise..rescue&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;my_function&lt;/span&gt;
  &lt;span class="n"&gt;do_the_work&lt;/span&gt;
&lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;
  &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"There was an error: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ruby's &lt;code&gt;raise..rescue&lt;/code&gt; is the corollary to Javascript's &lt;code&gt;try..catch&lt;/code&gt;. If we compare the complete syntax of both structures, especially when we employ the optional &lt;code&gt;begin&lt;/code&gt; keyword, the patterns look even more similar:&lt;/p&gt;

&lt;p&gt;Javascript&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// do stuff&lt;/span&gt;
&lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// catch the error&lt;/span&gt;
&lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// do this no matter what&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ruby&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;begin&lt;/span&gt;
  &lt;span class="c1"&gt;# do stuff&lt;/span&gt;
&lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
  &lt;span class="c1"&gt;# catch the error&lt;/span&gt;
&lt;span class="k"&gt;ensure&lt;/span&gt;
  &lt;span class="c1"&gt;# do this no matter what&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what is &lt;code&gt;catch&lt;/code&gt; for in Ruby, if not for errors?&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;throw..catch&lt;/code&gt; statement in Ruby is actually intended to be used as a part of an &lt;em&gt;expected workflow&lt;/em&gt; rather than for an exceptional (i.e. error) scenario. &lt;code&gt;throw..catch&lt;/code&gt; can be used as a means of escaping from a flow once a particular requirement is met. In the example below, we have an array of birds. As soon as we find a goose, we want to stop execution of the &lt;code&gt;each&lt;/code&gt; loop. This example is contrived, but we can imagine that if we were performing expensive procedures in each iteration, we would want to bail out as soon as we are able.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;birds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"duck"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"duck"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"goose"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"duck"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kp"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:goose&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;birds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;bird&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;bird&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;bird&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"goose"&lt;/span&gt;
      &lt;span class="kp"&gt;throw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:goose&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="vg"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;duck&lt;/span&gt;
&lt;span class="vg"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;duck&lt;/span&gt;
&lt;span class="vg"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;goose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;catch&lt;/code&gt; is meant to be used with &lt;code&gt;throw&lt;/code&gt;, and likewise &lt;code&gt;throw&lt;/code&gt; is meant to be used with &lt;code&gt;catch&lt;/code&gt;. Though we may see code in the wild in which an error is thrown and later rescued, that's not really what it's intended for. In fact if you try that out, take a look at the error message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;throw_rescue&lt;/span&gt;
  &lt;span class="kp"&gt;throw&lt;/span&gt; &lt;span class="no"&gt;StandardError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"There was an error."&lt;/span&gt;
&lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;throw_rescue&lt;/span&gt;
&lt;span class="vg"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;uncaught&lt;/span&gt; &lt;span class="kp"&gt;throw&lt;/span&gt; &lt;span class="no"&gt;StandardError&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The&lt;code&gt;uncaught throw&lt;/code&gt; tells us explicitly that we should be using &lt;code&gt;catch&lt;/code&gt; somewhere. Additionally, look what we're missing: a stacktrace. Because throwing and catching are meant to be part of an expected flow, it makes sense that they wouldn't have a a stacktrace. So in this case we get a misleading exception (&lt;code&gt;uncaught throw&lt;/code&gt; vs. &lt;code&gt;StandardError&lt;/code&gt;) and no additional information about the source of the error.&lt;/p&gt;

&lt;p&gt;What makes this even more confusing is that we can throw more than just symbols. As we see above, we can throw class names, like Exceptions. But we really shouldn't, as the example above should demonstrate.&lt;/p&gt;

&lt;p&gt;Looking back at our original question about our RSpec test, we can see now why this test won't ever pass:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;expect { throw StandardError.new("error") }.to raise_error&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We can't expect throwing an error to raise that error, because throwing and raising aren't the same thing in Ruby. If you want to handle errors, do so with &lt;code&gt;raise..rescue&lt;/code&gt;, not &lt;code&gt;try..catch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here are some additional resources on &lt;code&gt;raise..rescue&lt;/code&gt; and &lt;code&gt;throw..catch&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://avdi.codes/throw-catch-raise-rescue-im-so-confused/" rel="noopener noreferrer"&gt;https://avdi.codes/throw-catch-raise-rescue-im-so-confused/&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://rubymonk.com/learning/books/4-ruby-primer-ascent/chapters/41-exceptions/lessons/93-throw-and-catch" rel="noopener noreferrer"&gt;http://rubymonk.com/learning/books/4-ruby-primer-ascent/chapters/41-exceptions/lessons/93-throw-and-catch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tooling</category>
    </item>
    <item>
      <title>Our Favorite Posts of 2022</title>
      <dc:creator>Taylor Kearns</dc:creator>
      <pubDate>Fri, 30 Dec 2022 22:24:09 +0000</pubDate>
      <link>https://forem.com/thegnarco/our-favorite-posts-of-2022-1f12</link>
      <guid>https://forem.com/thegnarco/our-favorite-posts-of-2022-1f12</guid>
      <description>&lt;p&gt;In 2022 we resumed meeting in person, we pumped the brakes on crypto, we watched the World Cup, we tried to purchase Taylor Swift tickets. And the software world kept spinning. Here at The Gnar we found we had a lot to say over the last year. Here are some examples of the work we've done and the words we've written during the last lap around the sun.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.thegnar.com/blog/infinite-scroll-react-example-with-typescript-and-nextjs" rel="noopener noreferrer"&gt;Infinite Scroll React Example with TypeScript and NextJS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's a matter of when - not if - you will be asked to implement infinite scroll. Here's a guide and example to get you (sc)rolling.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.thegnar.com/blog/history-tracking-with-postgres" rel="noopener noreferrer"&gt;History Tracking with Postgres&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A meaty piece on a rich topic. Postgres is a magical toolbox, and here we explore some of those tools in the context of preserving a history of transactions at the database level. This is part of the "Yeah, Postgres Can Do That" series, with another post going up in November. Check them both out!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.thegnar.com/blog/navigating-session-token-authentication-in-shopify-for-embedded-server-side-rendered-rails-apps" rel="noopener noreferrer"&gt;Navigating Session Token Authentication in Shopify for Embedded, Server-Side Rendered Rails Apps&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've been spending a good amount of time in Shopify these days. And we of course build a lot of Rails apps. The authentication story for a Shopify store embedded in a server-side rendered Rails app is more complicated than you'd think. Read on to learn about how we addressed it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Industry
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.thegnar.com/blog/what-is-the-point-of-free-and-open-source-software-part-2-open-source" rel="noopener noreferrer"&gt;What Is the Point of Free and Open Source Software?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a pair of posts on free and open source software, we plumb the depths of software philosophy, business ethics, the common good, and where we currently find ourselves on the timeline of FOSS. Immersive, heady, and a lot of fun. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.thegnar.com/blog/make-yourself-accessible-why-it-matters" rel="noopener noreferrer"&gt;Make Yourself Accessible: Why it Matters&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If you are concerned about accessibility (pro tip: you should be), start here. In the first of this three-part series, we discuss not only what accessibility means, but why it matters. In Parts Two and Three we get our hands dirty with testing, building accessibility into new applications, and adding accessibility to legacy applications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.thegnar.com/blog/deconstructing-defi" rel="noopener noreferrer"&gt;Deconstructing Defi&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For those who know something about crypto, something about blockchain, or a bit of both, this is a great way to dip your feet deeper into the pool. We illuminate the core concepts scaffolding Destructured Finance. Given the state of Defi today, this couldn't be more relevant. &lt;/p&gt;

&lt;h2&gt;
  
  
  Culture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.thegnar.com/blog/our-code-review-process-more-than-quality-assurance" rel="noopener noreferrer"&gt;Our Code Review Process: More than Quality Assurance&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article we provide insight into the general code review process, and an overview of how it works at The Gnar. For those less familiar with the gears of software development, or for those looking to build a team, this can serve as a template. For those in the trenches, we hope you can take away some ideas about how to enhance your process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.thegnar.com/blog/exploding-consulting-myths-support" rel="noopener noreferrer"&gt;Exploding Consulting Myths: Support&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a three-part series we call Exploding Consulting Myths, we demonstrate how culture at The Gnar is inclusive, supportive, and fun. In the conclusion of the series we enumerate the various support structures provided for our team, both technical and personal. A must-read if you are considering a new job (&lt;a href="https://www.thegnar.com/about/join-our-team" rel="noopener noreferrer"&gt;https://www.thegnar.com/about/join-our-team&lt;/a&gt;).&lt;/p&gt;

</description>
      <category>welcome</category>
      <category>career</category>
      <category>programming</category>
      <category>iot</category>
    </item>
    <item>
      <title>Hindsight Is 20/20</title>
      <dc:creator>Taylor Kearns</dc:creator>
      <pubDate>Mon, 18 Oct 2021 13:01:54 +0000</pubDate>
      <link>https://forem.com/thegnarco/hindsight-is-2020-4f3</link>
      <guid>https://forem.com/thegnarco/hindsight-is-2020-4f3</guid>
      <description>&lt;p&gt;Are you just starting to learn how to code? How exciting! And intimidating! No matter how long we've been in this business, we're always learning something new. The Gnar team discussed what basic advice we'd offer a developer at the beginning of the journey. Here's what we came up with.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It will probably take you two weeks to somewhat understand what you're being taught today. Don't freak out if you don't get it right away.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Read code every day. Just put your eyeballs on it, even if you don't understand it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Error messages are your friend. They aren't shaming you, they are helping you target something to fix. Get comfortable reading error messages and don't be discouraged when you get them; be excited that there's a (hopefully helpful) starting point for your debugging.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ask all of your questions, all of the time. If the answer doesn't make sense, it doesn't mean you were wrong for asking; it might mean that the question you had needs to be examined a little bit. Take the time to compare what you THINK you need to know, what the code is telling you, and what you're certain about. There may be information available to you that can lead you in a better direction. This is a skill that coders practice all the time, because we all feel lost on occasion. The trick is to find ways to feel confident that you do (or don't!) know something. That lets you learn it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use your tools. There are so many things that have been built to help you figure out what's going on in your code, and learning how to manipulate them will make it easier to learn new things and crack harder problems. Figure out how to use Inspector consoles, debugger statements, linters, editor features, terminal tricks, helper libraries, and (eventually) tests. Each language has a slightly different approach to these tools, but ultimately the goal's always the same: making the work you do easier and more enjoyable by creating ways around obstacles.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Try to build stuff on your own even if you think you're not very good yet. Exploring and practicing are the essence of being a dev. I've made so many different variations of to-do list apps just to keep me asking productive questions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A large web framework essentially takes a string input and returns a different string output. Seeing a simplified example makes it easier to not be so overwhelmed by the entire framework.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When you get right down to it, code is simple. No magic, no elves, no wizards. Things are being compared, and the result of that comparison is either True or False. Learning to code is really about learning the basics of implementing these abstract flows in your mind, and then learning how to write and read them in code, in that order. This is why it is confusing - you have to conceptualize the solution in abstract logic, then work backwards to translate it into code. You may not be able to conceptualize how to build a pyramid, but at the end of the day it's a bunch of dried mud. I bet you can conceptualize dried mud.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;YOU CAN UNDERSTAND THIS. Just give it time.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Contributors
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/orgs/TheGnarCo/people/alxjrvs"&gt;Alex Jarvis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/orgs/TheGnarCo/people/bikefighter"&gt;Ben Olson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/orgs/TheGnarCo/people/danfrenette"&gt;Dan Frenette&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/orgs/TheGnarCo/people/efertsch"&gt;Ethan Fertsch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/orgs/TheGnarCo/people/nialbima"&gt;Nick Marshall&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/orgs/TheGnarCo/people/tdyer"&gt;Tom Dyer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/orgs/TheGnarCo/people/WMahoney09"&gt;Will Mahoney&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Learn more about &lt;a href="https://www.thegnar.com/about"&gt;The Gnar and our team&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>RSpec Negated Matchers</title>
      <dc:creator>Taylor Kearns</dc:creator>
      <pubDate>Mon, 13 Sep 2021 01:26:21 +0000</pubDate>
      <link>https://forem.com/thegnarco/rspec-negated-matchers-1ec8</link>
      <guid>https://forem.com/thegnarco/rspec-negated-matchers-1ec8</guid>
      <description>&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;We want to test that when we call our Ruby method, one result &lt;em&gt;does&lt;/em&gt; occur while another result &lt;em&gt;does not&lt;/em&gt; occur. Specifically, we want to test that an &lt;code&gt;Event&lt;/code&gt; is created but that an &lt;code&gt;EventPayload&lt;/code&gt; is not created. Using RSpec, we have this so far:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"creates an event without an associated payload"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_event!&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_event!&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;not_to&lt;/span&gt; &lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;EventPayload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is ok, but we'd like to run both expectations on a single method call.&lt;/p&gt;

&lt;p&gt;We know that RSpec has &lt;a href="https://relishapp.com/rspec/rspec-expectations/docs/compound-expectations"&gt;and&lt;/a&gt; which can help us make compound expectations, but this falls apart when we want to make one positive assertion and one negative assertion. We could try this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"creates an event without an associated payload"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_event!&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;not_to&lt;/span&gt; &lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;EventPayload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;and&lt;/span&gt; &lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But no joy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NotImplementedError: expect(...).not_to matcher.and matcher` is not supported, since it creates a bit of an ambiguity.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;How can we chain two expectations together with &lt;code&gt;and&lt;/code&gt; if one is a "not" condition? RSpec allows us to define a &lt;a href="https://relishapp.com/rspec/rspec-expectations/v/3-10/docs/define-negated-matcher"&gt;negated matcher&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Matchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_negated_matcher&lt;/span&gt; &lt;span class="ss"&gt;:not_change&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:change&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which allows us to then write this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"creates an event without an associated payload"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_event!&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;and&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;not_change&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;EventPayload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we can flip the order if we choose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"creates an event without an associated payload"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_event!&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;not_change&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;EventPayload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;and&lt;/span&gt; &lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fun!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Learn more about how The Gnar &lt;a href="https://www.thegnar.com/software-development/ruby-on-rails-development"&gt;builds Ruby on Rails applications&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
