<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Thomas Barrasso on Medium]]></title>
        <description><![CDATA[Stories by Thomas Barrasso on Medium]]></description>
        <link>https://medium.com/@tbarrasso?source=rss-784649f47696------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*eC8-n0dlgLMCFI1QUnMd-g.jpeg</url>
            <title>Stories by Thomas Barrasso on Medium</title>
            <link>https://medium.com/@tbarrasso?source=rss-784649f47696------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Tue, 23 Jun 2026 19:07:52 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@tbarrasso/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Is podcasting ready for IPv6?]]></title>
            <link>https://medium.com/@tbarrasso/is-podcasting-ready-for-ipv6-6893110c5889?source=rss-784649f47696------2</link>
            <guid isPermaLink="false">https://medium.com/p/6893110c5889</guid>
            <category><![CDATA[ipv6]]></category>
            <category><![CDATA[networking]]></category>
            <category><![CDATA[software]]></category>
            <category><![CDATA[podcast]]></category>
            <category><![CDATA[mobile]]></category>
            <dc:creator><![CDATA[Thomas Barrasso]]></dc:creator>
            <pubDate>Thu, 10 Sep 2020 17:24:22 GMT</pubDate>
            <atom:updated>2020-09-18T13:10:14.727Z</atom:updated>
            <content:encoded><![CDATA[<h4>The world has been <a href="https://en.wikipedia.org/wiki/IPv4_address_exhaustion">running out</a> of IPv4 addresses for some time. Podcasting may not be prepared for the inevitable IPv6 future.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FnvMhqjwrOWIFCBNCsSAfg.png" /><figcaption>IPv6 <a href="https://www.google.com/intl/en/ipv6/statistics.html#tab=per-country-ipv6-adoption">Adoption by Country</a>, on Google in 2020</figcaption></figure><h4>Background</h4><p>The original internet architecture, built atop <strong>I</strong>nternet <strong>P</strong>rotocol <strong>V</strong>ersion 4 (IPv4), allocated less than 4.3 billion addresses. Every internet connected device needs an IP address, but in the early days of the internet there were no tablets or smartphones and computers were luxuries, not commodities.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Z6rwl688Y94YAe61.png" /><figcaption>IPv4 <a href="https://en.wikipedia.org/wiki/IPv4_address_exhaustion">Address Exhaustion</a></figcaption></figure><p>Today, there are almost <a href="https://www.statista.com/statistics/330695/number-of-smartphone-users-worldwide/">as many smartphones</a> as there are IPv4 addresses (~3.5 billion smartphones at the time of writing in 2020). Numerous measures have been put in place to ration IPv4 addresses, including sharing of addresses across multiple devices within a local network. Since the late 1990’s, <a href="https://en.wikipedia.org/wiki/IPv6">IPv6</a> has made great strides at becoming a long-term replacement for IPv4, offering nearly 3.4×10³⁸ addresses.</p><p><a href="https://www.internetsociety.org/deploy360/ipv6/statistics/">IPv6 deployment</a> is steadily underway across many parts of the world, with many telecom companies in emerging markets leading the way. <a href="https://www.worldipv6launch.org/apps/ipv6week/measurement/images/graphs/RELIANCEJIOINFOCOMMLTD.png">Reliance Jio</a> in India, for example, is well ahead of many American companies at 90% IPv6 deployment. This should not come as a surprise given that India has the second largest total population at more than 1.35 billion. IPv4 simply cannot scale to support nations of that size.</p><h4>IPv6 and Podcasting</h4><p>Podcasts are essentially <a href="https://rss.com/blog/how-to-create-an-rss-feed-for-a-podcast/">RSS feeds</a> and audio files distributed via podcast hosts on servers around the world. There are two components that need to support IPv6: the client operating system and the podcast host server. Most client <a href="https://en.wikipedia.org/wiki/Comparison_of_IPv6_support_in_operating_systems">operating systems</a>, including Apple iOS and Google Android 5.0+, support IPv6 (although Android <em>still</em> has <a href="https://lostintransit.se/2020/05/22/its-2020-and-androids-ipv6-is-still-broken/">IPv6-related limitations</a> in 2020).</p><p>It is not enough for client operating systems to support IPv6; podcast hosts must also provide support. At minimum, this includes three key components.</p><ul><li>AAAA DNS records</li><li>IPv6-compliant web server</li><li>IPv6 DNS server</li></ul><p>IPv6 support usually coexists with IPv4 support in what is called <a href="https://whatismyipaddress.com/dual-stack"><em>dual-stack</em> delivery</a>, so it is not a situation of IPv6 <em>or</em> IPv4 bur rather IPv6 <em>and</em> IPv4. Developers do not have to choose between the two. For cloud-native hosts, IPv6 support is often as simple as <a href="https://aws.amazon.com/about-aws/whats-new/2016/10/ipv6-support-for-cloudfront-waf-and-s3-transfer-acceleration/">checking a box</a>, and usually comes at no additional cost.</p><p>For podcasters, every redirect also needs to support IPv6. That means tracking and measurement services like <a href="https://analytics.podtrac.com/">Podtrac</a> and <a href="http://chartable.com/">Chartable</a> need to support IPv6, in addition to the podcast host. Otherwise IPv6-only clients will still fail to resolve a DNS entry and ultimately be unable to listen.</p><h4>Who supports IPv6?</h4><p>Few podcast hosts provide public documentation regarding their support, or lack thereof, of IPv6 support. Doing some basic testing on a limited example set, these were my results among popular hosts:</p><p><strong>IPv6 Support</strong>: <a href="http://feedburner.google.com/">Feedburner</a>, <a href="https://www.podbean.com/">Podbean</a>, <a href="https://www.buzzsprout.com/">Buzzsprout</a>, <a href="https://www.acast.com/">Acast</a>, <a href="https://omnycontent.com/">Omny</a>, <a href="https://audioboom.com/">AudioBoom</a>, <a href="https://www.patreon.com/">Patreon</a>, <a href="https://transistor.fm/">Transistor.fm</a>, Apple, <a href="https://pinecast.com">Pinecast</a>, and <a href="https://www.podcastone.com/">PodcastOne</a></p><p><strong>No IPv6 Support</strong>: Libsyn, SoundCloud, Anchor.fm, Podomatic, BlogTalk, Spreaker, Simplecast, Ivoox, Megaphone, Art19, Feedpress, Blubrry, Podtrac, and Chartable</p><p>These results may not be fully conclusive, as it is possible for sites to partially support IPv6 only on specific subdomains or within specific paths. However, it seems systematic that many podcast hosts simply do not offer support for distributing content over IPv6.</p><p><strong>Some of the largest podcast hosts still do not support IPv6 in 2020</strong>, which means many of the most popular podcasts from around the world are only accessible to listeners connecting via IPv4.</p><h4>Why <em>not</em> support IPv6 support?</h4><blockquote>The only common case we heard about [for disabling IPv6 support] was internal IP address processing. — <a href="https://aws.amazon.com/cloudfront/faqs/">AWS FAQs</a></blockquote><p>While the <a href="https://www.iab.com/guidelines/iab-measurement-guidelines/">IAB Measurement Guidelines</a> require IP addresses be used as part of a solution to identify unique listens, for reasons of data privacy and security, it is better for businesses to convert IPv4 or IPv6 into one-way hashes, both to anonymize user data and also standardize formatting. i.e. IPv4 and IPv6 addresses are formatted differently, but a hashing function like MD5 processes variable-length inputs into fixed-length outputs.</p><p>One notable example of IP address processing is GeoIP look-ups that map IP addresses to approximate physical locations. This is how localized podcasts like <a href="https://www.npr.org/about-npr/909369777/npr-member-stations-turn-consider-this-into-first-localized-news-podcast/">NPR’s ‘Consider This’</a> are able to adapt programming by geography. <a href="https://blog.maxmind.com/2020/01/22/ip-geolocation-in-the-ipv6-world/">IP Geolocation</a> is still possible on IPv6, but it is a bit more complicated. Supporting IPv6 would require hosts and analytics services make code modifications to handle GeoIP look-ups for both IPv4 and IPv6 addresses.</p><h4>Potential Benefits of IPv6</h4><p>IAB Measurement Guidelines note that there are potential issues with, “shared locations such as corporate offices, dorms etc., that have a large number of people sharing the external IP Address.” With IPv6, every device can have its own, unique IP address. That means IPv6 can improve analytics accuracy by reducing or eliminating the use of shared IP addresses, as well as improve <a href="https://www.networkcomputing.com/networking/six-benefits-ipv6">performance and security</a> for listeners.</p><p>In IPv6, addresses could be static since there are many more IPv6 addresses than connecting devices globally. This would mean an IPv6 address is basically a UUID. Due to the security and privacy concerns this raises, <a href="https://techpatio.com/2020/articles/rotating-ip-address-important">IP addresses rotate</a> on a regular basis on most residential and cellular networks. This in turn creates a challenge for accurate analytics. In many settings, session cookies or similar tracking technologies can be used to overcome some of these challenges.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/608/1*vewproYvhecQhcX5P6r8HA.png" /><figcaption><a href="https://www.youtube.com/watch?v=N05jILIKVjA">JioPhone APN Settings</a> (2017)</figcaption></figure><p>Podcasting has largely been focused on developed markets like the US and EU, where IPv6 support now lags behind much of the developing world. Without business incentive, there is no compelling case for podcast hosts to offer IPv6 support. Worse, since IPv6-only users fail to establish a connection to an IPv4-only host, podcast hosts and podcasters have no visibility into how many listeners they may be missing out on.</p><p>Some podcasters may not see this as a problem, but OEMs and telecom companies like Reliance Jio often make IPv6-only the default configuration for devices like the <a href="https://www.jio.com/en-in/jiophone">JioPhone</a>. In a 2019 presentation, <a href="https://www.innog.net/wp-content/uploads/2019/07/01-Leveraging-IPv6-for-Explosive-Growth-Ramesh-Chandra-.pdf">Leveraging IPv6 for Explosive Growth</a>, Ramesh Chandra of Reliance Jio writes:</p><ul><li>93.7% requests served are on IPv6</li><li>Jio’s exponential growth enabler is IPv6 (soon to be IPv6-only)</li><li>Jio no longer encouraging IPv4 addresses</li></ul><p>By not supporting IPv6, you are unnecessarily disregarding access to some of the largest and fastest-growing Anglophone markets like India.</p><h4>Final thoughts</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cTq6IMEXL0Fzz7T_SA84kw.jpeg" /><figcaption><a href="https://podlp.com/">PodLP</a> on the <a href="https://www.amazon.com/BLU-Display-WhatsApp-Facebook-Pre-Loaded/dp/B08381VVVX">Blu Zoey Smart</a>, a $30 feature phone</figcaption></figure><p>As the developer of <a href="https://podlp.com/">PodLP</a>, listeners from around the world have reported issues accessing their favorite content on <a href="https://kaiostech.com/">KaiOS</a> mobile devices due to network connectivity issues related to a lack of IPv6 support. For podcasters and podcast hosts, the bottom line is this: <strong>if you do not support IPv6, you are losing listeners, especially in emerging markets.</strong></p><p><strong>IPv6 deployment is inevitable</strong>, and with it come gains in efficiency and security beyond the scope of in this article. There are entire podcasts like <a href="https://packetpushers.net/series/ipv6-buzz/">IPv6 Buzz</a> dedicated to IPv6 networking concerns. Given it a listen, and consider how IPv6 could benefit you and your listeners.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6893110c5889" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Podcasts for the Next Billion]]></title>
            <link>https://medium.com/@tbarrasso/podcasts-for-the-next-billion-1474778454e1?source=rss-784649f47696------2</link>
            <guid isPermaLink="false">https://medium.com/p/1474778454e1</guid>
            <category><![CDATA[kaios]]></category>
            <category><![CDATA[mobile]]></category>
            <category><![CDATA[design]]></category>
            <category><![CDATA[software]]></category>
            <category><![CDATA[podcast]]></category>
            <dc:creator><![CDATA[Thomas Barrasso]]></dc:creator>
            <pubDate>Wed, 24 Jun 2020 19:04:03 GMT</pubDate>
            <atom:updated>2024-02-21T04:47:53.391Z</atom:updated>
            <content:encoded><![CDATA[<h4>Designing a podcast client for KaiOS smart feature phones</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*T20MHmWgsxMx6m_doJUYdg.png" /><figcaption>Sscreenshots of <a href="https://podlp.com/">PodLP</a> on a Nokia 8110</figcaption></figure><p>More than <a href="https://internetworldstats.com/stats.htm">3.1 billion people (~40%) are not connected to the internet</a>, the majority of whom live in Africa and Asia. For companies, this presents an opportunity to build hardware and software that connects the “next billion,” particularly in the mobile space with platforms like <a href="https://www.android.com/versions/go-edition/">Android Go</a> and <a href="https://www.kaiostech.com/">KaiOS</a>. The <a href="https://www.jio.com/en-in/jiophone">JioPhone</a> is one such success story, selling more than <a href="https://telecomtalk.info/reliance-jio-sold-70million-jiophones/221418/">70 million phones</a> in India at the equivalent of $10 USD (or less!).</p><p>With around 500 apps, the <a href="https://www.kaiostech.com/store/">KaiStore</a> is a platform where app developers can publish apps available to millions without being crowded out. However, this requires software that is designed, developed, and optimized to run on low-end hardware. That often means simplified interfaces designed for d-pad navigation, low-bandwidth networks, and really small screens¹.</p><p>¹ 1st-Gen iPhone: 320x480, KaiOS: 240x320</p><p>When I looked through the app store on my Alcatel GoFlip 3 running KaiOS, one noticeable omission for me was the lack of a podcast app. Android and iOS each have dozens of podcast apps, including default clients provided by Google and Apple. For my new phone, with the navigation and screen size constraints, web-based podcast apps accessed through the browser had a poor user experience and no offline capabilities. Additionally, if I were going to make the switch from smartphone to feature phone, I wanted a podcast app to listen to all my own favorite podcasts. So, I decided to build <a href="https://podlp.com/">PodLP</a>, a podcast app designed for KaiOS.</p><h3>Design</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qlAdxk2Tv5_5_hFhwrXn5g.png" /><figcaption>Early designs of PodLP in Sketch.app</figcaption></figure><p>I started the process by looking through the podcast apps I currently use to understand which features would be the most important to include, and then started to think about how I could minimize and fit those features into both a smaller screen space and non-touch screen interaction.</p><p>Visual design began with the <a href="https://developer.kaiostech.com/design-guide/kaios-ui-kit">UI Kit for Sketch.app</a> that KaiOS provides to create standard user experiences that leverage familiar UI elements like software keys and options menus. For podcast clients, nearly all apps offer some combination of popular podcasts, search, subscribe, and download. These formed the set of minimum feature requirements that would enable users to discover, listen to, and follow podcasts from around the world.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-LIZI69WbWybPxEcWkXDEg.png" /><figcaption>Early designs of PodLP with device frames</figcaption></figure><p>After walking through the simplest version based on existing KaiOS components, subtle design improvements like including the number of items in a list were added. This affords users a sense of scale on a device where only 3–4 items can fit on screen at once. Visual progress indicators were also added both on the play and episode screens for users who might start and then come back to an episode. “Invisible” UX additions included automatically deleting episodes after listening to free up space on devices with minimal storage.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NuawZPzOIutuMzExQq-cag.jpeg" /><figcaption>Photo of PodLP on a Nokia 8110</figcaption></figure><p>Finally, I began prototyping the app on my Nokia 8110 (aka the “banana phone”). Especially when dealing with T9 typing and d-pad navigation, there is no substitute for a real device when validating designs — and having others trying to use and navigate through the app revealed information hierarchy and findability issues as well as where error/success states needed to be designed. It also helps proof details like color, sizing, and spacing while also considering the “feel” of interactive components (modal, dialog, scrubber).</p><h3>Development</h3><p>Although there are very few apps on the KaiStore compared to the Apple App Store or Google Play, there are a handful of resources of software developers including the <a href="https://developer.kaiostech.com/">KaiOS Developer Portal</a>, <a href="https://github.com/AdrianMachado/KaiUI/">KaiUI library</a>, and <a href="https://discord.gg/rQ93zEu">r/KaiOS Discord server</a>. The experience can be frustrating, especially when navigating undocumented or under-documented APIs. Again, this is where a real device is helpful in feature discovery and validation. Even still, you may find yourself misguided by the existing, limited documentation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/408/1*-2DG869ofzbUYWyaUExa2A.png" /><figcaption>Discord thread about the documented, unimplemented <a href="https://developer.mozilla.org/en-US/docs/Archive/B2G_OS/API/DeviceStorage">DeviceStorage</a> API</figcaption></figure><p>For example, don’t be surprised if you notice inconsistencies in functionality with on-device testing. Originally PodLP was built to use the <a href="https://developer.mozilla.org/en-US/docs/Archive/B2G_OS/API/DeviceStorage">DeviceStorage</a> API to save podcasts to files locally. However, I soon discovered certain parts of the API had never actually been implemented. This creates for a confusing (and frustrating) development experience. If you intend to rely on any KaiOS/ Firefox OS-specific APIs, smoke test them in the developer console first!</p><p>It’s also worth mentioning that most KaiOS devices have either 256MB or 512MB of RAM, which is often the most limiting resource. This means using techniques like <a href="https://sergimansilla.com/blog/virtual-scrolling/">virtualization</a> to limit the number of elements actually rendered on screen, as well as limiting file size when downloading remote assets using XHR or Fetch. For PodLP, this was especially challenging since 1hr+ shows can easily reach 50–100MB in size on a device that doesn’t have close to that much memory freely available.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/512/1*JK2wFnBg98WA2R6jkL_vvw.png" /><figcaption>The PodLP logo is mashup of the RSS logo and a vinyl record</figcaption></figure><h3>Publishing</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/480/1*dhtn-PiVrxep1psd3owS3A.png" /><figcaption>PodLP on the KaiStore</figcaption></figure><p>The last step in developing PodLP was <a href="https://kaiads.com/">KaiAds</a> integration, both as a monetization strategy and because it’s required for distribution on the KaiStore. Based on what I’ve observed in the KaiAds console, I expect very low effective cost per mile (eCPM) around $0.01 — $0.10 USD, which means it will be difficult to hit the $500 distribution threshold.</p><p>However, it is still the early days for KaiOS and for me, the main motivation is the prospect of becoming the <em>de facto</em> podcast app for millions, many of whom may be coming online and listening to podcasts for the first time! I also hope to build a useful service for many like myself interested in a “digital detox,” but who do not want to give up podcasts.</p><p>Finally, after months of designing, developing, testing, debugging, and localizing, I published <a href="https://podlp.com/">PodLP</a> on the <a href="https://www.kaiostech.com/store/apps/?bundle_id=com.podlp.podlp">KaiStore</a>. The app is freely available in English, Spanish, and French (more languages coming soon) on all devices running KaiOS 2.0+.</p><p>Note: you can find up-to-date developer guides on <a href="https://kaios.dev/">KaiOS.dev</a> and showcase your app with landing pages on <a href="https://kaios.app/apps/UxappJMyyWGDpPORzsyl">KaiOS.app</a>.</p><figure><a href="https://www.kaiostech.com/store/apps/?bundle_id=com.podlp.podlp"><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Nj8s9xdHgQiz8zTfRWi3Gw.png" /></a><figcaption>Download PodLP for free on the KaiStore</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1474778454e1" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why does JavaScript have -0?]]></title>
            <link>https://javascript.plainenglish.io/why-does-javascript-have-0-9b6e1965a075?source=rss-784649f47696------2</link>
            <guid isPermaLink="false">https://medium.com/p/9b6e1965a075</guid>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Thomas Barrasso]]></dc:creator>
            <pubDate>Tue, 03 Dec 2019 17:09:11 GMT</pubDate>
            <atom:updated>2019-12-05T14:55:58.776Z</atom:updated>
            <content:encoded><![CDATA[<h4>JavaScript has two zeroes: -0 and +0. They are somehow both the same and different.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dhVeOEORgwq2B3SGxRDfAA.png" /><figcaption>Using strict equality comparison, -0 and +0 are equal</figcaption></figure><h3>A Tale of Two Zeroes</h3><p>Since the early versions of JavaScript there have always been two ways of performing <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness">equality comparison</a>:</p><ul><li>Abstract Equality Comparison using == aka “double equals”</li><li>Strict Equality Comparison using === aka “triple equals”</li></ul><p>ES6 delivered a third option in the form of the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is">Object.is</a> method. It has some slight differences that hint at problems you did not even know you had. For instance, how would you tell <a href="https://2ality.com/2012/03/signedzero.html">JavaScript’s two zeroes</a> apart?</p><p>Perhaps a better question is, JavaScript has two zeroes? Why does JavaScript have two zeroes? Why would any language have two zeroes?</p><p>The name for this is <a href="https://en.wikipedia.org/wiki/Signed_zero">Signed Zero</a>. It turns out the reason that JavaScript has -0 is because it is a part of the <a href="https://en.wikipedia.org/wiki/IEEE_754">IEEE 754</a> floating-point specification. Two zeroes are also present in other languages like <a href="https://ruby-doc.org/stdlib-2.5.3/libdoc/bigdecimal/rdoc/BigDecimal.html#class-BigDecimal-label-Positive+and+negative+zero">Ruby</a> as well.</p><p>The two zeroes in question are:</p><ul><li>Positive zero +0</li><li>Negative zero -0</li></ul><p>As one might expect, they are treated as “the same” by both equality comparisons methods above. After all, zero is zero.</p><pre>-0 == +0   // true<br>-0 === +0  // true</pre><p>That is where Object.is comes in. It treats the two zeroes as unequal.</p><pre>Object.is(+0, -0)  // false</pre><p>Pre-ES6 it is still possible to tell the two zeroes apart. Looking at the results from other operators offers a hint.</p><pre>-0 &gt; +0  // false<br>+0 &gt; -0  // false<br>-0 + -0  // -0<br>-0 + +0  // +0<br>+0 + +0  // +0<br>+1 / -0  // -Infinity<br>+1 / +0  // +Infinity</pre><p>The last two operations in particular are useful. Unlike say Ruby or Python where division by zero yields a ZeroDivisionError, JavaScript returns <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity">Infinity</a>. Now take a look at the polyfill for Object.is offered on MDN.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b12d4fb2fe8d2ac1b63c179505c9a9b0/href">https://medium.com/media/b12d4fb2fe8d2ac1b63c179505c9a9b0/href</a></iframe><p>Since division by signed zero in JavaScript returns signed infinity, those results can be compared to tell the two zeroes apart.</p><h3>Resources</h3><ul><li><a href="https://hackernoon.com/negative-zero-bbd5fd790af3">Negative Zero</a></li><li><a href="https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html">What Every Computer Scientist Should Know About Floating-Point Arithmetic</a></li><li><a href="https://people.freebsd.org/~das/kahan86branch.pdf">Much Ado About Nothing’s Sign Bit</a></li></ul><h3>TLDR</h3><ul><li>JavaScript (and many languages) have two, signed zeroes</li><li>They can be distinguished pre-ES6 and using Object.is</li><li>The difference is only evident when doing signed arithmetic</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9b6e1965a075" width="1" height="1" alt=""><hr><p><a href="https://javascript.plainenglish.io/why-does-javascript-have-0-9b6e1965a075">Why does JavaScript have -0?</a> was originally published in <a href="https://javascript.plainenglish.io">JavaScript in Plain English</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Scale Securely with Transit Gateway]]></title>
            <link>https://medium.com/swlh/scale-securely-with-transit-gateway-198f600547e8?source=rss-784649f47696------2</link>
            <guid isPermaLink="false">https://medium.com/p/198f600547e8</guid>
            <category><![CDATA[security]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[networking]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <dc:creator><![CDATA[Thomas Barrasso]]></dc:creator>
            <pubDate>Mon, 02 Dec 2019 13:01:01 GMT</pubDate>
            <atom:updated>2019-12-02T13:01:01.548Z</atom:updated>
            <content:encoded><![CDATA[<h4>AWS Transit Gateway is an under-appreciated service providing secure, scalable, and maintainable connectivity between distributed services and on-premise networks.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*U_jZ17j5eqDjGwsh" /><figcaption>Unifi 16Xg switch by <a href="https://unsplash.com/photos/qTEj-KMMq_Q">Thomas Jensen on Unsplash</a></figcaption></figure><h4>Supporting Scale</h4><p>As software company offerings expand, so do their teams. When startups get acquired or go public, <em>the</em> engineering team grows into a full engineering organization. That engineering organization then needs to scale to support more customers and in the process, monolithic architectures make way to service-oriented designs.</p><p>Like the code they write, engineering organizations migrate from a single entity into a distributed collection of <a href="http://blog.idonethis.com/two-pizza-team/">two-pizza teams</a>. As with their micro-services, these teams need to talk to one another.</p><p>Engineers have lots of ways to communicate: email, Slack, JIRA, and passive-aggressive<a href="https://www.boredpanda.com/funny-passive-aggressive-office-notes/"> post-it notes</a>. So, there are many options for connectivity in AWS including Internet Gateways, NAT Gateways, Direct Connect Gateways, Egress-Only Internet Gateways, VPC Peering, and PrivateLink.</p><h4>Connectivity Options</h4><p>Each option has a set of trade-offs associated with it, but the main ones used for service-to-service communication are Internet Gateways, VPC Peering, PrivateLink, and Transit Gateway. Here is a vastly oversimplified use case for each of these resources:</p><ul><li><strong>Internet Gateways</strong>: use only for public services. Traffic is routed over the internet and DNS entries are configured in a public Route53 Hosted Zone, making your service discoverable and accessible to the world.</li><li><strong>PrivateLink: </strong>use for secure, single service-to-service integration with one of the <a href="https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html">supported services</a>. Not ideal for shared services as each consumer network requires a VPC Endpoint.</li><li><strong>VPC Peering</strong>: use for single, VPC-to-VPC service sharing. Not ideal for mesh networks because peering connections are not <em>transitive</em> and Edge-to-Edge Gateway/ VPN Connections cannot be shared.</li><li><strong>Transit Gateway</strong>: use for general purpose, secure, centrally-managed shared services and internal, on-premise applications. Combine with private Hosted Zones and a <a href="https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver.html">Route53 Resolver</a> to support private DNS.</li></ul><h4><strong>Transit Gateway vs. VPC Peering — Limitations</strong></h4><p>As a network-level utility that enables the sharing of multiple resources, VPC Peering is the closest analog to Transit Gateway. As such, the two also share similar limitations including the inability to have overlapping IP address ranges (CIDR blocks).</p><p>However, there are several significant <a href="https://docs.aws.amazon.com/vpc/latest/peering/invalid-peering-configurations.html">unsupported VPC Peering configurations</a> that are fully supported by Transit Gateway.</p><h4><strong>VPC Peering does not support <em>transitive</em> peering</strong></h4><p>This restriction is so important, it is actually the reason behind the name <em>Transit</em> Gateway. Transitive networks greatly simplify full, <a href="https://aws.amazon.com/answers/networking/aws-single-region-multi-vpc-connectivity/">multi-VPC mesh networks</a> where every node is connected to every other node in the network.</p><blockquote>If you have a VPC Peering connection between VPC A and VPC B, and one between VPC A and VPC C, there is no VPC Peering connection between VPC B and VPC C. You cannot route packets directly from VPC B to VPC C through VPC A.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EFUbde0W1rbsoS3B9ZgjYw.png" /><figcaption>VPC Peering (left) vs. Transit Gateway (right)</figcaption></figure><p>While it is possible to connect <a href="https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html">up to 125 VPCs</a> through peering connections, the issue is one of scale. For a full mesh network, there need to be n(n-1)/2 total connections. For 125 VPCs, that is more than 7,000 total peering connections! On the other hand, Transit Gateway supports <a href="https://docs.aws.amazon.com/vpc/latest/tgw/transit-gateway-limits.html">up to 5,000 VPCs</a> and only requires one Attachment per VPC.</p><p><strong>VPC Peering does not allow sharing of Edge-to-Edge Gateways</strong></p><p>Additionally, VPC Peering does not support the sharing of Edge-to-Edge Gateways or Private Connections including Internet Gateways, Direct Connect Gateways, or VPC Endpoints. That means each of these resources needs to be recreated across every network that needs access.</p><p>With Transit Gateway, only a single Site-to-Site VPN or Direct Connection is needed to host internal services that span multiple accounts. This configuration is much easier to monitor and scale.</p><blockquote>Edge to edge routing is not supported; you cannot use VPC A to extend the peering relationship to exist between VPC B and the corporate network.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Kci8T6boI5mm1SMjTjsm8A.png" /><figcaption>VPC Peering does not support Edge-to-Edge VPN Connections</figcaption></figure><h3>Internal &amp; Shared Services</h3><p>Although Transit Gateway enables many advanced network topologies, at a high-level, it is especially useful in provisioning internal &amp; shared services.</p><h4>Internal Services</h4><p>Cloud-hosted internal services are valuable because they combine the scalability and cost-effectiveness of cloud infrastructure with the privacy, security, and control of on-premise systems.</p><p>With the proliferation of Software as a Service (SaaS), we have become accustomed with the notion of distributing information to third-party providers and creating services that are connected to the public internet. However, restricting access to such services at the network-level improves security by reducing the surface area for a potential attack and eliminates unnecessary traffic from bots.</p><p>Before Transit Gateway, in order to launch internal, cloud-hosted services each isolated VPC needed its own connection to a corporate network. This is difficult to monitor and maintain and is not cost-effective since many of these resources are priced by the hour. With Transit Gateway, it is much easier to monitor and restrict traffic across just a single connection.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ubvimQABMBRm0CfyIqJszw.png" /><figcaption>Without Transit Gateway (multiple S2S VPN connections) vs. with Transit Gateway (single connection)</figcaption></figure><h4>Shared Services</h4><p>Monolithic architecture is by its nature centralized. This means that communication between components and sharing dependencies is trivial. Yet, monoliths are an example of tightly-coupled software that has well-known issues related to scalability, security, and stability.</p><p>In direct contrast are distributed systems and service-oriented architectures (SAO). These inherently decoupled applications now come with new issues, like the ability to share cross-cutting concerns like logging, alerting, and analytics. That is where Transit Gateway can help.</p><p>Rather than share a Site-to-Site VPN that connects to a corporate network, it is instead possible to share routes to a set of VPCs that together make up a suite of shared services. This ensures traffic to these services is not routed over the internet and both ingress and egress can be monitored in a single location. It also means that as new services get created, they can become instantly and automatically available to other applications without changes in configuration or the need to create a new pairing connection.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kntEcctepkKqwUKR_LrXkw.png" /><figcaption>Accessing shared services using Transit Gateway</figcaption></figure><p>Complexity in the cloud only grows and that is especially true of cloud networking. As recently as 2006, Amazon Web Services (AWS) had only three service offerings: S3, SQS, and EC2. Today there are hundreds of services. Some like Transit Gateway comes with an initial investment in time, but once set up, they greatly reduce the cost and difficulty of connectivity moving forward.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=198f600547e8" width="1" height="1" alt=""><hr><p><a href="https://medium.com/swlh/scale-securely-with-transit-gateway-198f600547e8">Scale Securely with Transit Gateway</a> was originally published in <a href="https://medium.com/swlh">The Startup</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Totally legit software methodologies]]></title>
            <link>https://levelup.gitconnected.com/totally-legit-software-methodologies-1d00f0b9d779?source=rss-784649f47696------2</link>
            <guid isPermaLink="false">https://medium.com/p/1d00f0b9d779</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[humor]]></category>
            <category><![CDATA[agile]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software]]></category>
            <dc:creator><![CDATA[Thomas Barrasso]]></dc:creator>
            <pubDate>Mon, 14 Oct 2019 21:04:53 GMT</pubDate>
            <atom:updated>2019-10-14T21:04:53.461Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EiBUSO_4kCA8pyiNH5Ik-g.jpeg" /><figcaption>Fall Drives on Country Roads by <a href="https://unsplash.com/@rpnickson?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Roberto Nickson</a></figcaption></figure><p>There are a lot of ideas about software and how to drive its development. Some approaches are promising, while others can be pretty problematic. Here are just a few strategies you might have seen used by other engineers for crafting digital products.</p><h3>Beta Driven Development 🐤</h3><p>MVP is Life. Beta Driven Development (AKA the other BDD) exists because the client initially requested a Proof of Concept (POC), but now they want to take that into production. The supporting code is not modular, does not adhere to SOLID principles, and does not have a single unit or integration test written. In fact, there is no need for integration tests because all of the “integrations” are actually just mocks anyway. If you are lucky, you might find a single comment.</p><h3>Profit Driven Development 💵</h3><p>Capital optimization drives the economy, and, this process. All infrastructure decisions, no matter how small, must be run by management and finance to ensure minimal impact to margins. Separation of concerns is not important here. Instead, developers are forced to find clever ways to squeeze near-complete utilization out of every single EC2 instance. That might include running scheduled jobs on another client’s idling machine so your Account Manager can sleep soundly at night.</p><p>Note: this approach is not to be confused with <strong>Prophet Driven Development</strong>, where architects are handed diagrams and code in the form of stone tablets from the divine (aka the design team). Also known as God Given Development, this practice makes heavy use of magic characters, hand-wavy interactions, and tends to focus more on commandments than unit tests. Pre-push hooks are the medium with which the heavenly enforces code cleanliness and purity.</p><h3>Defense Driven Development 🛡️</h3><p>Don’t Trust Anyone is the mantra at DDD shops. Even in dynamically-typed, interpreted languages like Javascript, every function starts with a dozen types and validity assertions. No system is a safe system, and every function is an interface to the outside world. InfoSec does not grant approval for third-party dependencies, so these codebases are often large and littered with copious exception handling logic. No <a href="https://www.davidhaney.io/npm-left-pad-have-we-forgotten-how-to-program/">left-pad</a> imports here.</p><h3>Rest Driven Development 💤</h3><p>Many followers began their journey experimenting with the <a href="https://en.wikipedia.org/wiki/Pomodoro_Technique">Pomodoro Technique</a>, pausing every 25 minutes for a quick break. Developers know that working long hours is not conducive to productivity or quality. That is why RDD shuns the eight-hour workday in favor of rest, with its memory formation and consolidation benefits. As such, practitioners sleep 17–21 hours per day, waking only at the end of a REM cycle to write just a few lines of the absolute most readable, efficient, and concise code.</p><h3>Instagram Driven Development 📷</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*O7TRMB3VQB0vBFF4" /><figcaption>Me coding on Instagram, <a href="https://www.instagram.com/p/BjK7vwGAe_O/?utm_source=ig_web_copy_link">@karbonkilla</a></figcaption></figure><p>Do it for the gram. Just find a heavily-indented file with colorful syntax highlighting, apply a tilt shift filter so you can’t quite make out the details, place a cup of trendy coffee or a cute animal next to your workstation, and snap a pic! Competition is steep, especially when you are up against Digital Nomads traveling the globe and writing code when inspiration strikes. However, if you stick to IGDD you can trade-in your day job as a #webdev for one as a #influencer. Just imagine all income from JetBrains sponsorships, Google endorsements, and Apple product placements.</p><p>#developer #programming #code #vscode #codeislife</p><blockquote>Software is a great combination between artistry and engineering.</blockquote><blockquote>– Bill Gates</blockquote><p>Perhaps some (or all) of these strategies have resonated at a point in time. Whatever methodology you subscribe to, be sure to write great software.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1d00f0b9d779" width="1" height="1" alt=""><hr><p><a href="https://levelup.gitconnected.com/totally-legit-software-methodologies-1d00f0b9d779">Totally legit software methodologies</a> was originally published in <a href="https://levelup.gitconnected.com">Level Up Coding</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why RSpec Tests Fail (and How To Fix Them)]]></title>
            <link>https://medium.com/better-programming/why-rspec-tests-fail-and-how-to-fix-them-402f1c7dce16?source=rss-784649f47696------2</link>
            <guid isPermaLink="false">https://medium.com/p/402f1c7dce16</guid>
            <category><![CDATA[ruby-on-rails]]></category>
            <category><![CDATA[rspec]]></category>
            <category><![CDATA[testing]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[ruby]]></category>
            <dc:creator><![CDATA[Thomas Barrasso]]></dc:creator>
            <pubDate>Mon, 07 Oct 2019 22:56:28 GMT</pubDate>
            <atom:updated>2019-10-08T21:58:34.144Z</atom:updated>
            <content:encoded><![CDATA[<h4>Knowing how to troubleshoot tests is an essential software skill</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Ywoj4blnnZzAOTzkMlRL8Q.jpeg" /><figcaption>NASA <a href="https://www.nasa.gov/multimedia/imagegallery/image_feature_644.html">First Launch,</a> 1950 🚀</figcaption></figure><p>NASA’s earliest attempts at launching rockets were part of the <a href="https://en.wikipedia.org/wiki/RTV-G-4_Bumper">Bumper</a> program, comprised of unmanned rockets in the late ‘40s and early ‘50s. The next decade saw many rocket launches — some successful, while others burst into flames.</p><p>Then, in 1961, the Soviet Union successfully sent cosmonaut Yuri Gagari on the first manned rocket, making him the first human in history to journey to outer space.</p><p>Contrast that with Wan Hu, a legendary Chinese figure described as the “first astronaut.” For his ascent, he was seated in a chair attached to several dozen rockets. Most versions of this story are apocryphal, with Hu not surviving to make another attempt at spaceflight.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/483/0*xLkxBlQs7smyYT9W.png" /><figcaption>Wan Hu, <a href="https://en.wikipedia.org/wiki/Wan_Hu">Wikipedia</a></figcaption></figure><p>Wan Hu’s tale is a cautionary one: we should first test our ideas in a constrained environment before risking important resources (like our lives).</p><p>It is now common to see software in aviation, automotive, pharmacy, banking, and education. This makes software quality more important than ever, with software testing a vital part of improving quality.</p><h3>Why Test Software</h3><p>Unit tests are the front-line defense against bugs and errors. Without automated tests, production deployments are more like crossing your fingers and hoping for the best. Ultimately, the end-users become your test subjects.</p><p>Automated testing catches bugs early in the software development life cycle (SDLC), leading to <a href="https://abstracta.us/blog/test-automation/true-roi-test-automation/">measurable cost savings</a> and overall improvements in software quality.</p><p>Yet, even when requirements are crystal clear and stakeholders are in alignment, engineers make mistakes translating their understanding of the requirements into executable code.</p><p>Bugs can take many forms, including errors in logic, arithmetic, and connectivity, as well as the result of obsolete dependencies, assumptions about data, poor documentation, or lack of proper version control. Errors are also commonly the result of unforeseen side effects.</p><p>Unit tests force us to think critically and verify that our code exhibits certain behaviors. In this way, tests serve the same purpose as an editor and can guard against subtle typos that might result in syntax or type errors.</p><p>For interpreted languages like Ruby, this is especially helpful because many of these exceptions are run-time errors rather than compile-time errors.</p><p>When unit tests are combined and run against real data between multiple, production-like systems, they become integration tests. This is where Behavior Driven Development (BDD) frameworks, like <a href="https://rspec.info/">RSpec</a>, can be both exceptionally powerful and frustrating.</p><p>Much like <a href="https://rubyonrails.org/">Rails</a>, RSpec, in combination with libraries like <a href="https://github.com/thoughtbot/factory_bot">factory_bot</a>, <a href="https://github.com/DatabaseCleaner">DatabaseCleaner</a>, <a href="https://github.com/teamcapybara/capybara">Capybara</a>, <a href="https://github.com/travisjeffery/timecop">Timecop</a>, and <a href="https://github.com/vcr/vcr">VCR</a>, provides functionality that can easily seem like <a href="https://magic-ruby.com/">Ruby Magic</a>™. But once you are familiar with these tools, it becomes possible to test each system in concert and in isolation.</p><p>After spending time writing (and rewriting) many RSpec tests, I want to point out the subtle and not-so-subtle issues I have writing and debugging tests.</p><h3><em>How</em> RSpec Tests Fail</h3><p>Tests fail <em>consistently</em> or <em>intermittently</em>.</p><p>Reproducibility in tests is important because without it, developers question the value of the tests and eventually testing itself (think, Boy Who Cried Wolf Syndrome).</p><p>Consistently failing tests are easier to catch and commonly the result of mental fatigue.</p><p>Tests that fail intermittently are called <em>flaky tests</em><strong> </strong>and are more difficult to analyze. They are usually caused by non-deterministic behavior, unavailable external services, non-transactional changes, assumptions about data, side-effects, and edge cases related to dates and time.</p><p>Here’s why RSpec tests fail and how to fix them.</p><h3>Forgetfulness</h3><p>Stubbing too much or unintentionally stubbing.</p><blockquote>Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what’s programmed in for the test. — Martin Fowler, <a href="https://martinfowler.com/articles/mocksArentStubs.html">Mocks Aren’t Stubs</a></blockquote><p>RSpec does not explicitly require the use of test spies to make <a href="https://relishapp.com/rspec/rspec-mocks/docs/basics/expecting-messages">message expectations</a>. Instead, it offers the <a href="http://rspec.info/documentation/2.14/rspec-mocks/RSpec/Mocks/Matchers/Receive.html">receive matcher</a>, which can be used on any object to make expectations about branching behavior.</p><p>While this approach offers more concise and convenient syntax, it can also be easy to forget that the receive matcher stubs the target method by default.</p><p>Real estate 101 tells us that home prices only ever go up.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d6d7f50b0cf387201a0125b7007d507b/href">https://medium.com/media/d6d7f50b0cf387201a0125b7007d507b/href</a></iframe><p>Now, we might want to test that assumption in RSpec:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5fcbd6566b3545d1a6c8096e3d77de8d/href">https://medium.com/media/5fcbd6566b3545d1a6c8096e3d77de8d/href</a></iframe><p>When we run this test, to our surprise, it fails with the following error:</p><pre>Failure/Error: expect(house.price).to be &gt; 649000<br>       expected: &gt; 649000<br>       got:        649000</pre><p>As it turns out, the receive matcher stubs the target method unless we use and_call_original to un-stub. This no-oped appreciate_a_lot, and the result is that the house price remains unchanged.</p><p>One strategy is to separate branch testing from results tests. This keeps test cases concise and avoids issues with inadvertently stubbing methods.</p><p>A more general approach is to stub as little as necessary to avoid discrepancies between test and production code paths. Most importantly, unlike the example above, <a href="https://thoughtbot.com/blog/don-t-stub-the-system-under-test">don’t stub the system under test</a>.</p><p>TL/DR: Remember, stubbing is the default behavior of the receive matcher; use and_call_original to un-stub but retain message expectations.</p><h3>In-Memory and In-Database Discrepancies</h3><p>There are many ways to find and update active record models, but by default, active record will use an integer column named id as the table’s primary key.</p><p>Eventually, with Rails 4.2, came <a href="https://github.com/rails/globalid">GlobalID</a>, an app-wide uniform resource identifier (URI). As a result, Rails features include active job support, passing models directly.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/af6b539ce7096c384f2d0bde61f6bbd6/href">https://medium.com/media/af6b539ce7096c384f2d0bde61f6bbd6/href</a></iframe><p>This made it easier to pass models as arguments to jobs. However, it also masks what is happening behind the scenes which can cause confusion during testing.</p><p>Active job uses GlobalID::Locator.locate internally to deserialize the model GlobalID. It then performs a database query using the primary key.</p><p>Now, it is tempting to write a test like this one, as on the surface it looks like we are passing the user object directly.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0191445e608589ab1af1d460ae34546e/href">https://medium.com/media/0191445e608589ab1af1d460ae34546e/href</a></iframe><p>The first test fails with an error like this one:</p><pre>Failure/Error: expect(user).to receive(:perform_send_welcome_email!)<br>     <br>   (#&lt;User:#..&gt;).perform_send_welcome_email!(*(any args))<br>           expected: 1 time with any arguments<br>           received: 0 times with any arguments</pre><p>The second test also fails, but with a different error:</p><pre>Failure/Error: expect(user.welcome_email_sent?).to eq(true)<br>     <br>       expected: true<br>            got: false<br>     <br>       (compared using ==)</pre><p>Both of these tests fail because the subject under test, a specific User, is the same in-database but not in-memory. Database changes are not automatically propagated to models in memory.</p><p>The first test could instead make use of a matcher like <a href="https://relishapp.com/rspec/rspec-mocks/docs/working-with-legacy-code/any-instance">expect_any_instance_of(User)</a> while the second test can be done easily with <a href="https://apidock.com/rails/ActiveRecord/Persistence/reload">#reload</a>, which re-syncs active record with the database.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5f8f47b0a9b7e3589e58d0350153bc2b/href">https://medium.com/media/5f8f47b0a9b7e3589e58d0350153bc2b/href</a></iframe><p>TL/DR: Be cognizant of in-memory and in-database discrepancies; use #reload as necessary to re-sync a record with the database.</p><h3>Non-Determinism</h3><p>Sometimes it passes, sometimes it fails.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CitcuXgLIpXQdotyJP2GIw.jpeg" /><figcaption><a href="https://hsm.utimaco.com/solutions/applications/random-number-generator/">Random Number Generators</a></figcaption></figure><h4>Randomness</h4><p><a href="https://engineering.mit.edu/engage/ask-an-engineer/can-a-computer-generate-a-truly-random-number/">Can a computer generate a truly random number?</a> Not really, at least not without special hardware. Instead, computers simulate randomness by drawing from a pool of entropy like cursor movements, keystrokes, hard-disk access, etc.</p><p>These “random” sources are then combined in a single location (like <a href="https://en.wikipedia.org/wiki//dev/random">/dev/random</a>) for applications that require pseudo-random behavior.</p><p>Regardless of whether the behavior is truly-random or pseudo-random, testing randomness can be quite difficult. Unsurprisingly, it is also an obvious source of non-deterministic behavior. Consider a Dice class:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8ee5a21e9895c4dae8db1650c6492c7f/href">https://medium.com/media/8ee5a21e9895c4dae8db1650c6492c7f/href</a></iframe><p>Calling roll should return a random number between one and six, just like a real dice.</p><p>Next, we write tests to verify this behavior. Perhaps we also include a test that verifies that the dice is not somehow weighted (or maybe this code is for a gambling service and we want skewed results).</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/553a955d51357f432272c6e935a383b8/href">https://medium.com/media/553a955d51357f432272c6e935a383b8/href</a></iframe><p>We run our tests locally, and they pass. They pass again in CI. A few days later, we notice an intermittent failure on the second test. The easiest solution would be to avoid randomness altogether. When that is not possible, we can instead provide a “seed” to the <a href="https://ruby-doc.org/core-2.4.0/Random.html">Random</a> class.</p><p>Note: This is the same process we use when debugging randomly-ordered RSpec tests by manually setting the <a href="https://relishapp.com/rspec/rspec-core/docs/command-line/order">--seed</a> option.</p><p>Pseudo-random number generators (PRNGs) are just functions that map one input to a seemingly-random, but deterministic sequence. Using a fixed seed provides us with a fixed sequence, and thus deterministic results.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cfb2339d637f96c800d36abd00ee176d/href">https://medium.com/media/cfb2339d637f96c800d36abd00ee176d/href</a></iframe><p>Now, total will always yield 191 and the test will pass consistently! Although we have also introduced an inconsistency between test and production conditions. Fortunately, this scenario is not that common.</p><h4><strong>Unique constraints</strong></h4><p>Randomness will more likely show up as <em>collisions between randomly generated data in a model factory with unique constraints.</em></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/42599600e577beb15249207791c4ac61/href">https://medium.com/media/42599600e577beb15249207791c4ac61/href</a></iframe><p>The odds of collision with the ObjectId or similar UUIDs are exceptionally low, but the probability of duplication with the description are 1:1000. When randomly generated properties are necessary, the easiest solution is to pick from a larger pool of random.</p><p>Note: <a href="https://github.com/faker-ruby/faker">Faker</a> is another great tool that can be used in test factories to create unique, structured data without the risk of collisions.</p><p>TL/DR: Avoid testing randomness. If you can’t, specify a seed and/or use <em>more</em> <em>random</em> random like <a href="https://ruby-doc.org/stdlib-2.5.1/libdoc/securerandom/rdoc/SecureRandom.html">SecureRandom</a>.</p><h3><strong>State Preservation Across Tests</strong></h3><p>Arne Hartherz’s article summarizes this well: <a href="https://makandracards.com/makandra/11507-using-before-all-in-rspec-will-cause-you-lots-of-trouble-unless-you-know-what-you-are-doing">Using </a><a href="https://makandracards.com/makandra/11507-using-before-all-in-rspec-will-cause-you-lots-of-trouble-unless-you-know-what-you-are-doing">before(:all) in RSpec will cause you lots of trouble unless you know what you are doing</a>.</p><p>before(:all) creates data outside of transaction blocks, persisting changes across tests.</p><p>Best practice (which Rspec supports using the --order rand option) is to run tests in random order to reveal implicit dependencies between tests. Data that persists between randomly ordered tests naturally results in inconsistencies.</p><p>Here is one example of how <em>not</em> to use before(:all):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/78a4340efae5b695a954d796157a254f/href">https://medium.com/media/78a4340efae5b695a954d796157a254f/href</a></iframe><p>If the tests are run in the order they are defined, the second test will fail:</p><pre>Failure/Error: raise AlreadyVotedError<br><br># ./voter.rb:26:in `vote&#39;</pre><p>This is why RSpec offers lazy-evaluated let, and eager-evaluated let! helper methods. <a href="https://stackoverflow.com/questions/5359558/when-to-use-rspec-let">When to use RSpec </a><a href="https://stackoverflow.com/questions/5359558/when-to-use-rspec-let">let</a> offers more details, but in short:</p><p>Always prefer let to an instance variable.</p><p>TL/DR: Always use let, do not use before(:all).</p><h3><strong>Network Calls</strong></h3><p>Most applications rely on third-party services like <a href="https://stripe.com/">Stripe</a> or <a href="https://squareup.com/us/en">Square</a> for payment processing, <a href="https://www.splunk.com/">Splunk</a> for logging, or <a href="https://newrelic.com/">New Relic</a> for monitoring.</p><p>That means that applications generate lots of network requests. While we can trust that the engineers for these service providers have thoroughly tested their client libraries, it is important to test the use of these libraries within our applications as well.</p><p>Unfortunately, not all client libraries will support an environment for integration testing. Even if they did, networking issues could lead to transient failures in tests like this one. It is best not to test beyond the remote boundary when writing contract tests.</p><pre># --- Caused by: ---<br># Net::HTTPServerException:<br>#   503 &quot;Service Unavailable&quot;</pre><p>That is where tools like <a href="https://github.com/vcr/vcr">VCR</a> are useful!</p><p>VCR lets developers “record and replay” HTTP interactions, including those generated by third-party tools. This makes tests fast, deterministic, accurate, and not reliant on networking availability or external services.</p><p>Tests are wrapped in a use_cassette block so that on their first execution, a YAML file gets created to save the response.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d3ed6d0d1530aadf239305adb1986f7e/href">https://medium.com/media/d3ed6d0d1530aadf239305adb1986f7e/href</a></iframe><p>For more in-depth information, RubyGuides has a good tutorial on <a href="https://www.rubyguides.com/2018/12/ruby-vcr-gem/">using and configuring VCR</a>.</p><p>TL/DR: Use pre-recorded HTTP responses in tests to improve overall speed, reliability, and accuracy.</p><h3>Time</h3><p>Not freezing time.</p><p>There are 28–31 days in a month, 365 days in a year, and 2,027 days in which Nixon was president. Actually, there are about 365.25 days in a Julian year (<a href="https://pumas.jpl.nasa.gov/files/04_21_97_1.pdf">365.2422 to be more precise</a>).</p><p>Alternatively, every fourth year can be called a leap year where we just tack on an extra day. February always gets that day, because it is the shortest month.</p><p>Some countries like the USA (and territories) span 11 timezones, while others like China observe just a single timezone (UTC+8). Then, for some crazy reason, twice a year a handful of countries increment or decrement their clocks in an attempt to coordinate working hours with sunlight.</p><p>The tests work reliably, between 01:00–23:00.</p><p>Needless to say, time is <em>very</em> complicated and testing time at or across boundaries is incredibly difficult. I have heard these kinds of tests referred to as <em>Cinderella Tests</em> because they turn into pumpkins at midnight.</p><p>To make these tests more reliable, it is best to become a Time Lord… or at least learn how to freeze and travel time in RSpec.</p><p>Here is an example with a Venue model that has many Events. If we want a list of upcoming concerts, we can compare start times to the current day.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ddf660c80b1033faa275ff633b9db684/href">https://medium.com/media/ddf660c80b1033faa275ff633b9db684/href</a></iframe><p>Then, during testing, we want to make sure this scope returns concerts that happened today or will happen in the future.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/02a2213fb944506871ff40da800aebcc/href">https://medium.com/media/02a2213fb944506871ff40da800aebcc/href</a></iframe><p>This test looks fine. It even derives start times from a single source to guarantee consistent deltas. A problem arises if this test runs at a day boundary, for example, just before midnight (11:59:59pm).</p><p>If enough time elapses during concert creation, upcoming_concerts might get called the next day, causing the first expectation to fail.</p><p>The easiest way to resolve this with Timecop is to freeze time before :each and return after :each. This way, time elapses <em>between</em> but not <em>during</em> tests.</p><p>TL/DR: Use <a href="https://github.com/travisjeffery/timecop">Timecop</a> to freeze and travel time predictably in RSpec; test time boundaries and edge cases defensively.</p><h3>Side Effects</h3><h4><strong>Active record callbacks</strong></h4><p>Active record offers convenient life cycle <a href="https://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html">callbacks</a> before and after state alteration that are easy to “set and forget”. Thorough testing should include these callbacks, but sometimes it is necessary to sidestep them.</p><p>That is where <a href="https://apidock.com/rails/ActiveSupport/Callbacks/Callback/ClassMethods/skip_callback">skip_callback</a> comes in. It can be used both in a spec factory as well as individual tests. Consider a User model:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/71a7c4f03bdd26f2f85c43b2ba492c83/href">https://medium.com/media/71a7c4f03bdd26f2f85c43b2ba492c83/href</a></iframe><p>While it is possible to stub send_welcome_email, in a real-world application this method might be buried deep in a stack trace and turn out to be only one of many callbacks.</p><p>Or, perhaps the callbacks were meant to run before a job asynchronously as above, but all jobs are being run inline for a specific test. Whatever the case, it is possible to instruct active record to skip callbacks for a specific model.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e0e68aa27b3eef64de5c919138c72139/href">https://medium.com/media/e0e68aa27b3eef64de5c919138c72139/href</a></iframe><p>It may be that a User model is required for an Address to be considered residential.</p><p>However, creating and associating a User with the Address inside of a perform_enqueued_jobs block triggers an after-create callback, and ultimately the SendWelcomeEmail job.</p><p>That said, skipping callbacks should be avoided in favor of more explicit factories, recorded network calls, and environment-specific configurations.</p><p>For example, in the “test” environment, sending an email could be handled <a href="https://stackoverflow.com/questions/19983221/actionmailer-testing-with-rspec">globally within ActionMailer</a>. If you do choose to skip_callback, remember to call <a href="https://api.rubyonrails.org/classes/ActiveSupport/Callbacks/ClassMethods.html#method-i-set_callback">set_callback</a> to restore callbacks for other tests.</p><p>TL/DR: <a href="https://apidock.com/rails/ActiveSupport/Callbacks/Callback/ClassMethods/skip_callback">skip_callback</a> can avoid active record callbacks, but use cautiously.</p><h3><strong>Active Job QueueAdapters</strong></h3><p>A common use case for active record callbacks is to enqueue an active job. Under the hood, active job is configured to use a specific <a href="https://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html">QueueAdapter</a>. This adapter determines the queue order (like FIFO, LIFO, etc).</p><p>A common adapter for RSpec is the <a href="https://api.rubyonrails.org/classes/ActiveJob/QueueAdapters/TestAdapter.html">TestAdapter</a>, which can be used to verifying that a specific job was enqueued successfully.</p><p>However, TestAdapter does not actually perform the job by default!</p><p>Depending on what you are testing, there are other adapters like the <a href="https://api.rubyonrails.org/classes/ActiveJob/QueueAdapters/InlineAdapter.html">InlineAdapter</a> that execute jobs immediately by treating perform_later calls like perform_now.</p><p>Alternatively, TestAdapter has a method, perform_enqueued_jobs, that, as its name suggests, actually performs the enqueued jobs synchronously.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4da0bf0b1011a578056912fd61567682/href">https://medium.com/media/4da0bf0b1011a578056912fd61567682/href</a></iframe><p>As with callbacks, there is value to testing both with and without actually performing the job. RSpec provides helpful active job matchers like the <a href="https://relishapp.com/rspec/rspec-rails/docs/matchers/have-enqueued-job-matcher">have_enqueued_job</a> matcher.</p><p>These helper methods allow for separation of concerns, making it possible to test the logic of a job in one spec, and the logic that triggers the job in another.</p><p>TL/DR: Use TestAdapter to track and perform enqueued active jobs.</p><h3>Too Specific</h3><p>Inconsistently ordered data.</p><p>Collections like <em>Hashes</em> and <em>Arrays</em> are used to store related data and are both enumerate in order of insertion.</p><p>During testing, this leads to comparisons that are implicitly order specific, often when creating and comparing collections of active record models. For instance, a Cat can have many toys.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f69b1537bde697ca8e6ccf8e74e1e28d/href">https://medium.com/media/f69b1537bde697ca8e6ccf8e74e1e28d/href</a></iframe><p>A simple test is then written to confirm that a Cat can in fact have many toys.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/05b97a7d417b077b431fefbeed482b4c/href">https://medium.com/media/05b97a7d417b077b431fefbeed482b4c/href</a></iframe><p><a href="https://github.com/thoughtbot/factory_bot">factory_bot</a>’s create_list helper creates three toys associated with our cat, Lovie.</p><p>The issue here is that while create_list will return three unique toys ordered consistently by creation, the association will return based on the scope ordering. If no order is provided, it defaults to order by ID.</p><p>For sequential IDs, this should not pose an issue because ordering by creation or sequence should be identical. However, the first four digits of an ObjectID represents seconds since the Unix epoch.</p><p>Instead of using eq to compare two arrays, we can use the redundantly-named match_array matcher, which is independent of order.</p><p>TL/DR: Use hash_including, include, and match_array when comparing collections independent of ordering.</p><h3><strong>Negative Test Expectations</strong></h3><p>Negative tests are a special case. Unlike positive tests, it is very easy to write overly-specific tests that ultimately test nothing. Consider a code path within a method that is <em>no</em>t expected to raise a custom error.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0887aece7508af6f2d9fd56dbb7d6235/href">https://medium.com/media/0887aece7508af6f2d9fd56dbb7d6235/href</a></iframe><p>A test for price_per_sq_ft might look something like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/389c7a4f8fe3602c1abcc3f1f2544c2a/href">https://medium.com/media/389c7a4f8fe3602c1abcc3f1f2544c2a/href</a></iframe><p>The first test expects an error to be raised, while the second test expects an error <em>not </em>to be raised. The issue with the second test is subtle, but thankfully is such a common occurrence that RSpec actually warns developers by default.</p><p><strong>Warning</strong>:</p><p>Using expect { }.not_to raise_error(SpecificErrorClass) risks false positives, as literally any other error would cause the expectation to pass, including those raised by Ruby (e.g. NoMethodError, NameError, and ArgumentError), meaning the code you are intending to test may not even get reached.</p><p>Instead, consider using expect { }.not_to raise_error` or `expect { }.to raise_error(DifferentSpecificErrorClass).</p><p>The RSpec warning clearly explains the issue with this test.</p><p>In the example above, the second test actually raises TypeError: nil can’t be coerced into Fixnum as nowhere have we defined @sq_ft! That is the problem with overly-specific negative tests, they can miss real problems like this one.</p><p>TL/DR: Favor positive tests over negative tests; write negative tests more broadly, especially when it comes to error handling.</p><h3>Resources</h3><p>There are lots of great articles on testing with Ruby, Rails, active record, RSpec, factory_bot, and automated testing in general.</p><p>Here are just a few I have found especially informative.</p><ul><li><a href="https://www.betterspecs.org/">Better Specs</a>.</li><li><a href="https://rspec.rubystyle.guide/">RSpec Style Guide</a>.</li><li><a href="https://samsaffron.com/archive/2019/05/15/tests-that-sometimes-fail">Tests that sometimes fail</a>.</li><li><a href="https://thoughtbot.com/blog/its-about-time-zones">It’s about time (zones)</a>.</li><li><a href="https://softwareengineering.stackexchange.com/questions/147134/how-should-i-test-randomness">How should I test randomness?</a></li><li><a href="https://hackernoon.com/flaky-tests-a-war-that-never-ends-9aa32fdef359">Flakey tests — The war that never ends</a>.</li><li><a href="https://spin.atomicobject.com/2012/08/09/rspec-thank-you-for-running-my-tests-in-random-order/">RSpec: Thank you for running my tests in random order</a></li><li><a href="https://medium.com/better-programming/how-to-set-up-rails-with-rspec-capybara-and-database-cleaner-aacb000070ef">How to set up Rails with RSpec, Capybara, and Database_cleaner</a>.</li><li><a href="https://medium.com/@fistsOfReason/testing-is-good-pyramids-are-bad-ice-cream-cones-are-the-worst-ad94b9b2f05f">Testing is good. Pyramids are bad. Ice cream cones are the worst</a>.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/530/1*Hhhtpg8HTH18MYWdzfuqRQ.png" /><figcaption><a href="https://android.jlelse.eu/basics-of-unit-testing-affdd2273310">Basics of Unit Testing</a></figcaption></figure><h3>Final Thoughts</h3><blockquote>The bitterness of poor quality remains long after the sweetness of meeting the schedule has been forgotten.</blockquote><p>Test failures can be frustrating, especially when it is not clear <em>why</em> they are failing. However, try not to lose sight of the overall goal behind testing: to validate behavior and alert engineers of the unintended consequence behind potential changes.</p><p>As frustrating as failing tests can be, having no tests leads to unpredictable and unreliable deployments. As software systems grow in size and complexity, so too do the risks of going straight into production. The alternative is to push code and just cross your fingers.</p><p>Of course, if after reviewing these examples your tests are still failing, there is always the possibility that it is because<strong> </strong>there’s a bug!</p><p>After all, that is what tests are designed to do: identify bugs earlier in the SDLC. It is better (and cheaper) to catch bugs during testing than in production.</p><p>Happy bug squashing!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=402f1c7dce16" width="1" height="1" alt=""><hr><p><a href="https://medium.com/better-programming/why-rspec-tests-fail-and-how-to-fix-them-402f1c7dce16">Why RSpec Tests Fail (and How To Fix Them)</a> was originally published in <a href="https://betterprogramming.pub">Better Programming</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A practical guide to ES6 Proxy]]></title>
            <link>https://medium.com/bitsrc/a-practical-guide-to-es6-proxy-229079c3c2f0?source=rss-784649f47696------2</link>
            <guid isPermaLink="false">https://medium.com/p/229079c3c2f0</guid>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Thomas Barrasso]]></dc:creator>
            <pubDate>Thu, 16 May 2019 14:27:50 GMT</pubDate>
            <atom:updated>2022-04-20T22:30:53.957Z</atom:updated>
            <content:encoded><![CDATA[<h3>A practical guide to Javascript Proxy</h3><h4>With <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy">Proxy</a>, you get a tiger object disguised as a cat object. Here are about half a dozen examples that I hope will convince you that Proxy provides powerful metaprogramming in Javascript.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lc5wkELvaZgI9YfHKkZ1CQ.jpeg" /><figcaption><a href="https://www.astro-tarology.com/free-unveil-your-own-selfie-card-and-its-deep-meaning/attachment/1280x1124-cat-mirror-tiger/">Kitten sees a tiger in its reflection</a></figcaption></figure><p><strong>Note</strong>: examples may be dated, and similar functionality can be achieved natively in newer versions of ECMAScript or syntactical supersets like TypeScript. This article shows what’s possible natively in ES2015 using Proxy.</p><h4>Introduction to Proxy</h4><p>With <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy">Proxy</a>, you get a tiger object disguised as a cat object. Here are about half a dozen examples that I hope will convince you that Proxy provides powerful metaprogramming in Javascript.</p><p>Although it is not as well known as other ES2015 features, Proxy has many uses including <a href="https://hackernoon.com/introducing-javascript-es6-proxies-1327419ab413">operator overloading</a>, <a href="https://en.wikipedia.org/wiki/Mock_object">object mocking</a>, <a href="https://medium.com/dailyjs/how-to-use-javascript-proxies-for-fun-and-profit-365579d4a9f8">concise-yet-flexible API creation</a>, <a href="https://github.com/sindresorhus/on-change">Object on-change events</a>, and even powers the <a href="https://medium.com/@gustojs/vuejs-3-and-other-top-news-from-q-a-event-with-core-vue-devs-c9834946ae7b">internal reactivity system behind Vue.js 3</a>.</p><blockquote>The Proxy object is used to define custom behavior for fundamental operations (e.g. property lookup, assignment, enumeration, function invocation, etc).–<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy">MDN</a></blockquote><p>A Proxy is a placeholder object that “traps” invocations and operations made to its target object which it can then passthrough, no-op, or handle more elegantly. It creates an undetectable barrier around the <strong>target object</strong> that redirects all operations to the <strong>handler object</strong>.</p><p>A Proxy is created using the new Proxy constructor which accepts two, required arguments: the <strong>target object</strong> and <strong>handler object</strong>.</p><p><strong>Tip</strong>: Use <a href="https://github.com/teambit/bit">Bit (open source)</a> to seamlessly turn your JS code into reusable components you can easily share and manage across projects- to build faster.</p><p><a href="https://bit.dev">Bit. Composable software.</a></p><p>The simplest example of a functioning Proxy is one with a single trap, in this case, a get trap that always returns “42”.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a4817fefd742f9808e1dcfac13a55ea9/href">https://medium.com/media/a4817fefd742f9808e1dcfac13a55ea9/href</a></iframe><p>The result is an object that will return “42” for <em>any</em> property access operation. That means target.x, target[&#39;x&#39;], Reflect.get(target, &#39;x&#39;), etc.</p><p>However, Proxy traps are certainly not limited to <em>get</em> operations. It is only one of more than a dozen different traps:</p><ul><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/get">handler.get</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/set">handler.set</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/has">handler.has</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply">handler.apply</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/construct">handler.construct</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/ownKeys">handler.ownKeys</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/deleteProperty">handler.deleteProperty</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/defineProperty">handler.defineProperty</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/isExtensible">handler.isExtensible</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/preventExtensions">handler.preventExtensions</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getPrototypeOf">handler.getPrototypeOf</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/setPrototypeOf">handler.setPrototypeOf</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor">handler.getOwnPropertyDescriptor</a></li></ul><h3>Proxy Use Cases</h3><p>It may not be immediately apparent how such a simple pattern could be so widely used, but hopefully, after a few examples, it will become more clear.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/764/1*M4sg0X9lKu99s6EZN1vwBQ.png" /><figcaption>Source: <a href="https://dzone.com/articles/scala-proxy-design-pattern">Proxy Design Pattern</a></figcaption></figure><h4>Default/ “Zero Values”</h4><p>In GoLang, there is the concept of <a href="https://tour.golang.org/basics/12"><em>zero values</em></a> which are type-specific, <em>implicit</em> default struct values. The idea is to provide type-safe default primitives values, or in Gopher-speak, “give your structs a useful zero value!”</p><p>Though different <a href="https://en.wikipedia.org/wiki/Creational_pattern">creation patterns</a> enable similar functionality, Javascript had no way to wrap an object with implicit initial values. The default value for an unset property in Javascript is undefined. That is, until Proxy.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/739b168d24975ac14fac059a3c6f8a83/href">https://medium.com/media/739b168d24975ac14fac059a3c6f8a83/href</a></iframe><p>This three-line function wraps a target object. If the property is set, it returns the property value (pass-through). Otherwise, it returns a default “zero value.” Technically, this approach isn’t implicit either but it could be if we extended withZeroValue to support type-specific (rather than parameterized) zero values for Boolean (false), Number (0), String (“”), Object ({}), Array ([]), etc.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/43d4a8b262e4bf2c5163310010c0dce5/href">https://medium.com/media/43d4a8b262e4bf2c5163310010c0dce5/href</a></iframe><p>One place where this functionality might be useful is a coordinate system. Plotting libraries may automatically support 2D and 3D rendering based on the shape of the data. Rather than create two separate models, it might make sense to always include z defaulted to zero rather than undefined.</p><h4>Negative Array Indices</h4><p>Getting the <a href="https://medium.freecodecamp.org/the-first-shall-be-last-with-javascript-arrays-11172fe9c1e0">last element in an Array</a> in Javascript is verbose, repetitive, and prone to off-by-one errors. That’s why there is a <a href="https://github.com/keithamus/proposal-array-last">TC39 proposal</a> that defines a convenience property, Array.lastItem, to get and set the last element.</p><p>Other languages like Python and Ruby make access to terminal elements easier with <a href="https://rubyquicktips.com/post/996814716/use-negative-array-indices">negative array indices</a>. For example, the last element can be accessed simply with arr[-1] instead of arr[arr.length-1].</p><p>With Proxy, negative indices can also be used in Javascript.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9d40e8abd19f5089ad27275f9d0d5858/href">https://medium.com/media/9d40e8abd19f5089ad27275f9d0d5858/href</a></iframe><p>One important note is that traps including <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/get">handler.get</a> stringify all properties. For array access, we need to coerce property names into Numbers which can be done concisely with the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_plus_()">unary plus operator</a>.</p><p>Now [-1] accesses the last element, [-2] the second to last, and so on.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4f5c61bf0a66cbc58975dfb354af6c31/href">https://medium.com/media/4f5c61bf0a66cbc58975dfb354af6c31/href</a></iframe><p>There is even an npm package, <a href="https://github.com/sindresorhus/negative-array">negative-array</a>, that encapsulates this functionality more completely.</p><h4><strong>Hiding Properties</strong></h4><p>Javascript has notoriously lacked private properties. Symbol was <a href="https://codeburst.io/a-practical-guide-to-es6-symbol-3fc90117c7ac">originally introduced to enable private properties</a>, but later watered down with reflective methods like <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols">Object.getOwnPropertySymbols</a> that made them publicly discoverable.</p><p>The longstanding convention has been to name private properties with a leading underscore, effectively marking them “do not touch.” Proxy offers a slightly better approach to masking such properties.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5b769c5348912724ce92708520a13729/href">https://medium.com/media/5b769c5348912724ce92708520a13729/href</a></iframe><p>The hide function wraps a target object and makes properties that are prefixed with an underscore inaccessible from the in operator and from methods like <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames">Object.getOwnPropertyNames</a>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6670072502a842f974a55156ecd9a489/href">https://medium.com/media/6670072502a842f974a55156ecd9a489/href</a></iframe><p>A more complete implementation would also include traps like <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/deleteProperty">deleteProperty</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/defineProperty">defineProperty</a>. Apart from closures, this is probably the approach that is closest to truly-private properties as they are inaccessible from enumeration, cloning, access, or modification.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/975/1*Mi9bq0I5__YN2E3xhNESHw.png" /></figure><p>They are, however, visible in the development console. Only closures are exempt from this fate.</p><h4>Caching</h4><blockquote>There are two hard problems in computer science: cache invalidation, naming things, and off-by-one errors.</blockquote><p>It is not uncommon to face difficulties synchronizing state between the client and server. Data can change over time, and it can be difficult to know exactly where to place the logic of when to re-sync.</p><p>Proxy enables a new approach: wrap objects to invalidate (and resync) properties as necessary. All attempts to access a property first check against a cacheing strategy that decides to returns what’s currently in memory, or to take some other action.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7c18c0b1735f7a162cd20011706511ef/href">https://medium.com/media/7c18c0b1735f7a162cd20011706511ef/href</a></iframe><p>This function is oversimplified: it renders all properties on an object inaccessible after a certain period of time. However, it would not be difficult to extend this approach to set time-to-live (TTL) on a per-property basis and to update it after a a certain duration or number of accesses.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/55827d116a57199eb9013c14b39b1268/href">https://medium.com/media/55827d116a57199eb9013c14b39b1268/href</a></iframe><p>This example simply renders the bank account balance inaccessible after 10 second. For more in-depth, real-world use cases there are several articles on <a href="https://medium.com/@niwaa/using-es6-proxy-to-meta-program-in-javascript-implement-caching-logging-etc-577e253b3e05">Caching &amp; Logging</a> and <a href="https://digitalist.se/blogg/create-client-side-cache-using-es6-proxy">Client-Side Caching</a> using Proxy and sessionStorage.</p><h4>Enums &amp; Read-Only Views</h4><p>These examples come from Csaba Hellinger’s article on <a href="http://dealwithjs.io/es6-features-10-use-cases-for-proxy/#anameenumaabetterenumtop">Proxy Use Cases</a> and <a href="https://hacks.mozilla.org/2015/07/es6-in-depth-proxies-and-reflect/">Mozilla Hacks</a>. The approach is to wrap an object to prevent extension or modification. Although <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze">Object.freeze</a> now provides functionality to render an object read-only, it’s possible to extend this approach for better <a href="https://en.wikipedia.org/wiki/Enumerated_type">enum</a> objects that throw errors accessing non-existent properties.</p><p><strong>Read-Only View</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3cf36b30c6deb7b246ee0dc26c70c7c0/href">https://medium.com/media/3cf36b30c6deb7b246ee0dc26c70c7c0/href</a></iframe><p><strong>Enum View</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5d0b4f7c9300baea473c5dc36e6782cc/href">https://medium.com/media/5d0b4f7c9300baea473c5dc36e6782cc/href</a></iframe><p>Now we can create an Object that throws an exception if you try to access non-exist properties, rather than returning undefined. This makes it easier to catch and address issues early on.</p><p>Our enum example is also the first example of <strong>proxies on proxies</strong>, confirming that a proxy <em>is</em> a valid target object for another proxy. This facilitates code reuse through composition of Proxy functionality.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/75cc2e97b73f85972fac8ebaeb141e76/href">https://medium.com/media/75cc2e97b73f85972fac8ebaeb141e76/href</a></iframe><p>This approach can be further extended to include “simulated methods” like <a href="https://github.com/gergob/jsProxy/blob/master/03-enum-nameof.js">nameOf</a> that return the property name given an enum value, mimicking the behavior in languages like Javascript.</p><p>While other frameworks and language supersets like TypeScript offer an <a href="https://www.typescriptlang.org/docs/handbook/enums.html">enum type</a>, this solution is unique in that it works with vanilla Javascript without special build tools or transpilers.</p><h4>Operator Overload</h4><p>Perhaps the most fascinating Proxy use case syntactically is the ability to overload operators, like the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in">in operator</a> using <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/has">handler.has</a>.</p><p>The in operator is designed to check if a “specified property is in the specified object or its prototype chain.” But it is also the most syntactically-elegant operator to overload. This example defines a continuous range function to compare Numbers against.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b97e3554fca32f0de4f5fde41065351a/href">https://medium.com/media/b97e3554fca32f0de4f5fde41065351a/href</a></iframe><p><a href="https://stackoverflow.com/a/20623994/148824">Unlike Python</a>, which uses generators to compare against a finite sequence of whole numbers, this approach supports decimal comparison and could be extended to support other numeric ranges–inclusive, exclusive, natural, rational, imaginary, ad infinitum.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4162e93df5ab0e76a5134044cd11af9f/href">https://medium.com/media/4162e93df5ab0e76a5134044cd11af9f/href</a></iframe><p>Even though this use case does not solve a complex problem, it does provide clean, readable, and reusable code. 🔥</p><p>In addition to the in operator, we can also overload <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete">delete</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new">new</a>.</p><h4>Cookies Object</h4><p>If you have ever had to interface with cookies in Javascript, you have had to deal with <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie">document.cookie</a>. It is an unusual API in that the API is a String that reads out <em>all</em> cookies, semi-colon delimited but you use the assignment operator to initialize or overwrite <em>a single</em> cookie.</p><p>document.cookie is a String that looks like:</p><pre>_octo=GH1.2.2591.47507; _ga=GA1.1.62208.4087; has_recent_activity=1</pre><p>In short, dealing with document.cookie is frustrating and error prone. One approach is the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie/Simple_document.cookie_framework">simple cookie framework</a>, which can be adapted to use Proxy.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d866790f1a5eced13292d44c33e6c828/href">https://medium.com/media/d866790f1a5eced13292d44c33e6c828/href</a></iframe><p>This function returns an object that acts like any other key-value object, but proxies all changes to document.cookie for persistence.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ff1b5cdb153a8932ab4ec79bbf7c897c/href">https://medium.com/media/ff1b5cdb153a8932ab4ec79bbf7c897c/href</a></iframe><p>In 11 lines, we have a better interface for modifying cookies, although additional features like string normalization would be necessary in a production environment.</p><h3>Fine Print</h3><p>The devil is in the detail, and Proxy is no exception.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/647/1*QD0j5oiCJGtExzuALpDaEA.jpeg" /><figcaption>Source: <a href="https://redmondmag.com/articles/2013/05/01/read-beyond-the-fine-print.aspx">Redmond Mag</a></figcaption></figure><h4>Polyfill</h4><p>At the time of writing (May 2019), there is <strong>no complete polyfill</strong> for Proxy. There is, however, a <a href="https://github.com/GoogleChrome/proxy-polyfill">partial polyfill for Proxy</a> written by Google that supports the get, set, apply, and construct traps and works for IE9+.</p><h4>Is it a Proxy?</h4><blockquote>It is impossible to determine whether an object is a proxy or not.–<a href="http://www.2ality.com/2014/12/es6-proxies.html">2ality</a></blockquote><p>According to the Javascript language specifications, there is <strong>no way to determine if an Object is a Proxy</strong>. However, on Node 10+ it is possible using the <a href="https://nodejs.org/api/util.html#util_util_types_isproxy_value">util.types.isProxy</a> method.</p><p><strong>What’s the target?</strong></p><p>Given a Proxy object, it’s <strong>not possible to obtain or change the target object</strong>. It is also not possible to obtain or modify the handler object.</p><p>The closest approximation is in Ben Nadel’s article <a href="https://www.bennadel.com/blog/3262-using-proxy-objects-to-dynamically-change-the-this-binding-within-a-generator-in-node-js.htm">Using Proxy to Dynamically Change THIS Binding</a>, which uses an empty object as the Proxy target and closures to cleverly reassign the object the Proxy’s actions are performed on.</p><h4>Proxy Primitives</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/da6d7aaa811524a0965ca814c9e7c36e/href">https://medium.com/media/da6d7aaa811524a0965ca814c9e7c36e/href</a></iframe><p>Unfortunately, one limitation of Proxy is that<strong> the target has to be an Object</strong>. That means we cannot use primitives like String directly. 😞</p><h4>Performance</h4><p>A <a href="http://thecodebarbarian.com/thoughts-on-es6-proxies-performance">major drawback of Proxy is performance</a>. Impact will vary based on browser and use, but <strong>Proxy isn’t the best approach for performance-critical code</strong>. Of course you can always measure the impact and decide if the advantages of Proxy outweigh the affect on performance.</p><h3>Why Proxy?</h3><p>Proxy provides a virtualized interface to control the behavior of any target Object. In doing so, it strikes a balance between simplicity and utility without sacrificing compatibility. Any code that expects an Object can accept a Proxy.</p><p>Perhaps the most compelling reason to use Proxy is that many of the examples above are just a few lines long and can easily be composed to create complex functionality. For one final example, we can compose functions from several use cases to create a read-only cookie object that returns a default value for non-existent or “private”, hidden cookies.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1d5cce6293f93f9ece74f46901e45b82/href">https://medium.com/media/1d5cce6293f93f9ece74f46901e45b82/href</a></iframe><p>I hope these examples have shown that Proxy is more than just an esoteric feature for niche metaprogramming in Javascript.</p><h3>Resources</h3><ul><li><a href="http://dealwithjs.io/es6-features-10-use-cases-for-proxy/">10 Use Cases for Proxy</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy">MDN–Proxy</a></li><li><a href="https://davidwalsh.name/javascript-proxy">David Walsh–JavaScript Proxy</a></li><li><a href="https://blog.campvanilla.com/advanced-guide-javascript-proxy-objects-introduction-301c0fce9432">Intro to Javascript Proxy Object</a></li><li><a href="http://2ality.com/2014/12/es6-proxies.html">2ality–Metaprogramming with ES6 proxies</a></li></ul><p>If you found this article helpful, please <strong>leave some claps</strong> 👏</p><p>Also, feel free to comment — I’d love to hear from you!</p><h3>Learn More</h3><ul><li><a href="https://blog.bitsrc.io/11-javascript-utility-libraries-you-should-know-in-2018-3646fb31ade">11 Javascript Utility Libraries you Should Know in 2019</a></li><li><a href="https://blog.bitsrc.io/7-tools-for-developing-web-components-in-2019-1d5b7360654d">7 Tools for Building Web Components</a></li><li><a href="https://blog.bitsrc.io/11-javascript-animation-libraries-for-2018-9d7ac93a2c59">11 JavaScript Animation Libraries For 2019</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=229079c3c2f0" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bitsrc/a-practical-guide-to-es6-proxy-229079c3c2f0">A practical guide to ES6 Proxy</a> was originally published in <a href="https://medium.com/bitsrc">Bits and Pieces</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A practical guide to ES6 Symbol]]></title>
            <link>https://codeburst.io/a-practical-guide-to-es6-symbol-3fc90117c7ac?source=rss-784649f47696------2</link>
            <guid isPermaLink="false">https://medium.com/p/3fc90117c7ac</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[coding]]></category>
            <dc:creator><![CDATA[Thomas Barrasso]]></dc:creator>
            <pubDate>Mon, 13 May 2019 17:23:44 GMT</pubDate>
            <atom:updated>2019-05-13T17:23:44.637Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WUcBksMT8J4zY-KKRTDyAg.jpeg" /><figcaption>Source: <a href="https://commons.wikimedia.org/wiki/File:Minnakht_01.JPG">Wikimedia Commons</a></figcaption></figure><h3>A Symbol</h3><p><a href="https://stackoverflow.com/questions/21724326/what-is-the-motivation-for-bringing-symbols-to-es6">Originally meant to introduce <em>private properties</em> to ES6</a>, Symbols offer an approach to metaprogramming in Javascript that provides extension hooks into language operators and methods without risking user name collisions. A symbol is a primitive data type that is immutable and globally-unique.</p><p>There are three kinds of Symbols:</p><ul><li><strong>User-defined symbols</strong> created with the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol">Symbol</a> function</li><li><strong>Globally-registered symbols </strong>created with the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for">Symbol.for</a> function</li><li><strong>Well-known symbols</strong> defined as static properties on the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#Well-known_symbols">Symbol</a> object</li></ul><p>While Symbols provide hooks into language methods, this same feature can be exploited by the developers of libraries and frameworks as well.</p><p>Here is a quick summary of how Symbols are used in code.</p><p><strong>A user-defined symbol is created with the global </strong><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol"><strong>Symbol</strong></a><strong> function</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a938ad4841e523b17b3ce63c103db970/href">https://medium.com/media/a938ad4841e523b17b3ce63c103db970/href</a></iframe><p><strong>They are new to ES6, but not <em>that</em> </strong><strong>new</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/171096380684db105da810d582823366/href">https://medium.com/media/171096380684db105da810d582823366/href</a></iframe><p><strong>No two symbols are alike</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4739af5a3ce93062019a53f741833aeb/href">https://medium.com/media/4739af5a3ce93062019a53f741833aeb/href</a></iframe><p><strong>Except when they are equal (i.e. symbols in the global registry)</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/65e2df3167df5dc02e6f6b6145ffe25e/href">https://medium.com/media/65e2df3167df5dc02e6f6b6145ffe25e/href</a></iframe><p><strong>They really are their own type</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f51c72aba199cd04f6dee93e6d6b3ee2/href">https://medium.com/media/f51c72aba199cd04f6dee93e6d6b3ee2/href</a></iframe><p><strong>They can be set as properties on objects</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/46c2819b9decc0791a002c2a582bfe3d/href">https://medium.com/media/46c2819b9decc0791a002c2a582bfe3d/href</a></iframe><p><strong>They can <em>usually</em> be overwritten, even in native object prototypes</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f34eb58172b57c03a5c7ca9450b164a9/href">https://medium.com/media/f34eb58172b57c03a5c7ca9450b164a9/href</a></iframe><p><strong>They can keep data from prying eyes</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fe0470a8d14dbd3f167cbe85d64247c4/href">https://medium.com/media/fe0470a8d14dbd3f167cbe85d64247c4/href</a></iframe><p><strong>Except they are still discoverable through reflection</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/683aefa94fd1732d1ad697fd58ccf357/href">https://medium.com/media/683aefa94fd1732d1ad697fd58ccf357/href</a></iframe><p>These are <strong>user-defined symbols</strong>, originally meant to introduce <em>near-private properties</em> to Javascript. Then there are <strong>built-in symbols</strong> (aka well-known symbols) designed to provide hooks into the implementation of <em>native</em> functions without risking clashes with user-defined names.</p><h3>Well-known Symbols</h3><p>Some Symbols are more well-known than others. There are symbols like <a href="https://medium.com/front-end-weekly/thank-u-symbol-iterator-next-aef9f09ff78">Symbol.iterator</a> that allow developers control over how an object can be iterated and spread. Then there are symbols like <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/unscopables">Symbol.unscopables</a>, which was born out of a need to maintain backwards compatibility with the seldom used <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with">with</a> keyword.</p><p>As an example, consider how to write a Password class that:</p><ul><li>Accepts an unmasked password string</li><li>Irreversibly masks the password</li><li>Can match (true or false) against a test password</li></ul><p>In writing this class, we will use built-in symbols.</p><p>To simplicity sake, we will implement the actually “hashing” using an <strong>insecure</strong> method based on Java’s <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()">Object.hashCode</a> function. For secure hashing, consider using a dedicated cryptography library like <a href="https://github.com/brix/crypto-js"><strong>CryptoJs</strong></a>.</p><p>hashCode irreversibly turns a String into a Number with some probability of collision (i.e. two Strings hash into the same Number).</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a58695992a2627c663837815aafb47e8/href">https://medium.com/media/a58695992a2627c663837815aafb47e8/href</a></iframe><p>With our hashCode function, the first task is to mask the real password.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ca994017b6a79c4873b5de59bb587650/href">https://medium.com/media/ca994017b6a79c4873b5de59bb587650/href</a></iframe><p>As we’ve seen before, a Symbol can be used as a property on an Object and is generally <em>more private</em> than say a String property prefixed with an underscore. However, it is <strong>not completely private</strong>. We can either use a direct reference to PWD or use reflective methods like <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols">Object.getOwnPropertySymbols</a> to obtain a reference to our unique symbol.</p><p>For more private properties, we can use <a href="https://humanwhocodes.com/blog/2014/01/21/private-instance-members-with-weakmaps-in-javascript/">IIFE or WeakMap</a> and soon ES7 will support a language-level <a href="https://github.com/tc39/proposal-private-methods">private field modifier</a> #.</p><h4>Symbol.match</h4><p>The next task is to make Passwords comparable. <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/match">Symbol.match</a> provides a hook into <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match">String.match</a>, which is one way for comparing strings. It is generally used to compare against a <em>regular expression</em> and the native implementation even implicitly coerces values into RegExp. However, our Password class will explicitly define its own behavior.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/37e8eb6700b3177c23eaa098e81f75ee/href">https://medium.com/media/37e8eb6700b3177c23eaa098e81f75ee/href</a></iframe><p>Now we can compare using the Password as we would a RegExp!</p><h4>Symbol.toPrimitive</h4><p>While the example above could be achieved without Symbols (either as its own method or by overwriting String.prototype), there are well-known Symbols that alter language and operator behavior like type conversion.</p><p>This is where <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive">Symbol.toPrimitive</a> comes in. It is used to convert Objects to primitives and is called by operators like the <a href="https://scotch.io/tutorials/javascript-unary-operators-simple-and-useful">unary plus operator</a>. We will use this Symbol to convert our Password into a masked String.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e0122841350ae551b15a58f6c0b50862/href">https://medium.com/media/e0122841350ae551b15a58f6c0b50862/href</a></iframe><p>Now when we coerce our Password into a String, we get asterisks.</p><p>The hint parameter hint can be “number”, “string”, or “default”. A more complete implementation could take these values into account and return NaN or other values, as applicable. For now, we will only support String.</p><p>When we try to turn our password back into a string we end up with a masked password with asterisks replacing each character.</p><p>It is worth noting that Symbol.toPrimitive is used for more than explicit type conversion. It is also used for <a href="http://2ality.com/2015/09/well-known-symbols-es6.html"><em>implicit coercions</em></a> done by the additional operator + as well as the equality operator ==.</p><h4>Symbol.toStringTag</h4><p>You might notice that if instead we call Object.toString on our password, we get the generic tag [object Object]. Symbols allow us to be more descriptive. Using the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag">Symbol.toStringTag</a> symbol, we can provide the Javascript runtime with a better tag for our object.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c1d539e65fcf2c934e99877594b35486/href">https://medium.com/media/c1d539e65fcf2c934e99877594b35486/href</a></iframe><p>Interestingly, Symbol.toStringTag is “a string valued property,” not a method. That means we need to use the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get">get keyword</a> in our password class (or <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty">Object.defineProperty</a> on an instance) to declare this property.</p><p>Now when we call toString on our password, we get [object Password]. Although this is not something many apps would need, it can be useful from a debugging and logging perspective.</p><h4>Symbol.hasInstance</h4><p>Another less common, but still powerful Symbol is <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance">Symbol.hasInstance</a>. It controls the behavior of the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof">instanceof</a> operator.</p><p>Fortunately it is <a href="http://joshmiller.cc/symbol-hasinstance/">not possible to redefine</a> native implementations of the Symbol.hasInstance function like Function.prototype[Symbol.hasInstance]. However, it is possible to do so on custom classes and objects like Password.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/109ce8bde9a9c52719babab892072533/href">https://medium.com/media/109ce8bde9a9c52719babab892072533/href</a></iframe><p>The main use for Symbol.hasInstance is in libraries that want more control over instanceof checks. For example, <a href="https://github.com/graphql/graphql-js/pull/989/files">GraphQL JS uses </a><a href="https://github.com/graphql/graphql-js/pull/989/files">Symbol.hasInstance</a> to check for specific symbols that identify GraphQLTypes.</p><h4>Symbol.iterator</h4><p>Symbol.iterator is among the most well-known and useful symbols. It enables user-defined iterables that implement the iteration protocol.</p><p>Here is an example of Symbol.iterator&#39;s power. They can be used to extend or override native object’s prototype. That means with just a few lines, we can define iteration for Objects globally.</p><p>Whether you <em>should</em> is <a href="https://javascript.info/native-prototypes">a different question</a>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d336e89ab864c0ac90f4b761b1a2f471/href">https://medium.com/media/d336e89ab864c0ac90f4b761b1a2f471/href</a></iframe><p>With this code, Objects can be spread into Arrays of [key, value] pairs. Likewise, Objects can be iterated using for...of loops.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5696fe419010253b22aff2b904524d4e/href">https://medium.com/media/5696fe419010253b22aff2b904524d4e/href</a></iframe><p>In the context of our Password class, we don’t even have to write our own iterator! Since a Password can be coerced into a String, we can use the native String iterator directly.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3435e3c3c9c511e8ddc82a185e6ffdae/href">https://medium.com/media/3435e3c3c9c511e8ddc82a185e6ffdae/href</a></iframe><p>Doing so allows us to spread or iterate a Password as a sequence of asterisks just as we could with a String.</p><p>Putting it all together, our final Password class looks like:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/52672a912bbd337b3c3a85cf79d3f463/href">https://medium.com/media/52672a912bbd337b3c3a85cf79d3f463/href</a></iframe><p>And has some interesting properties:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/72219a4bb683c42d5bf53d38fd50d805/href">https://medium.com/media/72219a4bb683c42d5bf53d38fd50d805/href</a></iframe><p><strong>Future Symbols</strong></p><p>The result is a class that masks the original password, is comparable, iterable, and convertible as we might expect from a String. While I have introduced five well-known Symbols, at the time of writing (May 2019) there are actually thirteen! The full list includes:</p><ol><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator">Symbol​.async​Iterator</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance">Symbol​.has​Instance</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable">Symbol​.isConcat​Spreadable</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator">Symbol.iterator</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/match">Symbol​.match</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/matchAll">Symbol​.matchAll</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/replace">Symbol​.replace</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/search">Symbol​.search</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/species">Symbol​.species</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/split">Symbol​.split</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive">Symbol​.toPrimitive</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag">Symbol​.toStringTag</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/unscopables">Symbol​.unscopables</a></li></ol><p>Be on the lookout for more soon! There are several suggestions and proposals for <a href="https://github.com/zenparsing/proposal-private-symbols">Private Symbols</a>, <a href="https://github.com/devsnek/proposal-symbol-thenable">Symbol.thenable</a>, <a href="https://www.keithcirkel.co.uk/metaprogramming-in-es6-symbols/#the-missing-well-known-symbol-symbolisabstractequal">Symbol.isAbstractEquals</a>, <a href="https://esdiscuss.org/topic/proposal-symbol-equals">Symbol.equals</a>, <a href="https://esdiscuss.org/topic/symbol-inspect">Symbol.inspect</a>, <a href="https://esdiscuss.org/topic/proposal-symbol-inobject-well-known-symbol-to-customize-the-in-operators-behavior">Symbol.inObject</a>, and more.</p><p>Symbols are a unique, immutable data type unlike their <a href="https://ruby-doc.org/core-2.2.0/Symbol.html">counterparts in other languages</a>. As the Javascript language continues to evolve, I expect Symbols to become a mainstay in Javascript metaprogramming.</p><p>If you found this helpful, please give some claps 👏 👏 👏</p><p>You can find me on <a href="https://www.linkedin.com/in/tombarrasso">LinkedIn</a> · <a href="https://github.com/Tombarr">GitHub</a> · <a href="https://medium.com/@tbarrasso">Medium</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3fc90117c7ac" width="1" height="1" alt=""><hr><p><a href="https://codeburst.io/a-practical-guide-to-es6-symbol-3fc90117c7ac">A practical guide to ES6 Symbol</a> was originally published in <a href="https://codeburst.io">codeburst</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[thank u, [Symbol.iterator].next]]></title>
            <link>https://medium.com/front-end-weekly/thank-u-symbol-iterator-next-aef9f09ff78?source=rss-784649f47696------2</link>
            <guid isPermaLink="false">https://medium.com/p/aef9f09ff78</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[front-end-development]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Thomas Barrasso]]></dc:creator>
            <pubDate>Wed, 10 Apr 2019 20:20:52 GMT</pubDate>
            <atom:updated>2019-04-11T00:47:31.183Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*a3Yzqr5BpeWzXFmSh6U1qQ.jpeg" /><figcaption><a href="https://shop.arianagrande.com/products/thank-u-next-cd-album">thank u, next</a> album art</figcaption></figure><blockquote>Thank u, [Symbol.iterator].next<br>Thank u, [Symbol.iterator].next<br>I’m so f****in’ grateful for this spec</blockquote><h3>Symbol.iterator</h3><p>Symbol.iterator is <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols"><em>the</em> protocol</a> that makes native objects like Array, Set, and Map iterable by providing a hook into language features like <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of">for…of</a> loops and the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator">spread operator</a>.</p><p>The most obvious use case is in creating new, iterable data structures that are not provided by the language, like a <a href="https://codeburst.io/js-data-structures-linked-list-3ed4d63e6571">Linked List</a>. However, Symbol.iterator also lets developers <strong>redefine navigation patterns without cloning the object or modifying its order in-place</strong>.</p><p>These patterns can then be written once in a function, class, or module and used anywhere. That means you can loop through an Array forwards, backwards, randomly, or infinitely in a modular fashion.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fupscri.be%2Ff%2F788447%3Fas_embed%3Dtrue&amp;dntp=1&amp;display_name=Upscribe&amp;url=https%3A%2F%2Fupscri.be%2F788447%2F&amp;type=text%2Fhtml&amp;schema=upscri" width="800" height="400" frameborder="0" scrolling="no"><a href="https://medium.com/media/18214d8333adbb5668f31791a3202b60/href">https://medium.com/media/18214d8333adbb5668f31791a3202b60/href</a></iframe><p>The actual Symbol.iterator protocol is very simple. It includes:</p><ul><li><strong>Iterable</strong>: an object with a function whose key is Symbol.iterator</li><li><strong>Iterator</strong>: the above function, used to obtain the values to be iterated</li></ul><p>In terms of code:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8f622c7dda40ff1f2fcb89110e2e4c09/href">https://medium.com/media/8f622c7dda40ff1f2fcb89110e2e4c09/href</a></iframe><p>This tells the Javascript runtime that an Object is iterable. It provides a way to get the next <strong>value</strong> and check if iteration is <strong>done</strong>.</p><p>If you want more details, there is a great guide on <a href="https://medium.freecodecamp.org/demystifying-es6-iterables-iterators-4bdd0b084082">Demystifying ES6 Iterables &amp; Iterators</a>. Otherwise, let’s look at how to use this in practice.</p><h4>Going Backwards</h4><p>The two most common ways to iterate an array in reverse are using indices (from array.length — 1 to 0), or with <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse">Array.reverse</a>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/84e875499189d8b4419cfb678c45a467/href">https://medium.com/media/84e875499189d8b4419cfb678c45a467/href</a></iframe><p>But both approaches raise concerns. With indices, it can be easy to forget the -1, leading to the infamous <a href="https://en.wikipedia.org/wiki/Off-by-one_error">off-by-one error</a>. Using Array.reverse modifies the array in place, which may not always be the intention.</p><p>There are <a href="https://dustinpfister.github.io/2018/10/17/lodash_reverse/">entire articles</a> dedicated to this topic, but since we are talking about Symbol.iterator, let me suggest one more way:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3fc854100b0f15145646d2babc46b6b3/href">https://medium.com/media/3fc854100b0f15145646d2babc46b6b3/href</a></iframe><p>Rather than iterating backwards on a given array, we have defined the “going backwards” iteration behavior for <em>any</em> array, all without modifying the order or creating a clone of the original array.</p><p>Here is how reverse would work in practice:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/18cf45333540fd5174ba4a45067920fa/href">https://medium.com/media/18cf45333540fd5174ba4a45067920fa/href</a></iframe><p>Another important aspect of Symbol.iterator is that we do not need an Array-like object to iterate. We can write a function like <a href="https://www.w3schools.com/python/ref_func_range.asp">Python’s </a><a href="https://www.w3schools.com/python/ref_func_range.asp">range</a> and use it to iterate elegantly over a sequence of numbers.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/98eb186e1eb1251f6f2b873a9d128052/href">https://medium.com/media/98eb186e1eb1251f6f2b873a9d128052/href</a></iframe><p><strong>Note</strong>: this implementation of range is very simple. It has not been tested and has clear issues with infinite ranges and negative steps.</p><p>We can use range the same way we did reverse:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/816f35a9bb48b7ce06c44b0ac4468112/href">https://medium.com/media/816f35a9bb48b7ce06c44b0ac4468112/href</a></iframe><p>We can even copy <a href="https://www.scala-lang.org/api/current/scala/Int.html#to(end:Int):scala.collection.immutable.Range.Inclusive">Scala’s </a><a href="https://www.scala-lang.org/api/current/scala/Int.html#to(end:Int):scala.collection.immutable.Range.Inclusive">Int#to</a> syntax, though you should be cautious when <a href="https://stackoverflow.com/questions/14034180/why-is-extending-native-objects-a-bad-practice">extending a native object’s prototype</a>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4431661b8b39e962cbcee42db1aaf508/href">https://medium.com/media/4431661b8b39e962cbcee42db1aaf508/href</a></iframe><p><strong>Note</strong>: I wrapped the number literal in parentheses to avoid a SyntaxError, but there are <a href="https://stackoverflow.com/a/33119577/148824">other options</a>.</p><p>As we will see, with Symbol.iterator the possibilities are literally endless!</p><h3>Thank U, Next</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/499/1*XJUWNfu4ckV16e7EnKLqSQ.png" /></figure><p>A music player is a great example of iteration behavior. Most of us do not listen to songs in order. Instead we control playback with <strong>shuffle</strong> and <strong>repeat</strong>.</p><p>As a programmer, this means building a way to play songs infinitely (repeat), randomly (shuffle), or both. Here is an example that does just that:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2FTombarr%2Fembed%2Fpreview%2FmoQXqr%3Fheight%3D600%26slug-hash%3DmoQXqr%26default-tabs%3Djs%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io&amp;url=https%3A%2F%2Fcodepen.io%2FTombarr%2Fpen%2FmoQXqr&amp;image=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fi.cdpn.io%2F1626825.moQXqr.small.02e8a9a6-97b1-48c1-9f64-b29bb79a5311.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=codepen" width="800" height="600" frameborder="0" scrolling="no"><a href="https://medium.com/media/7075e51ac61a243fd70a9686259f2a57/href">https://medium.com/media/7075e51ac61a243fd70a9686259f2a57/href</a></iframe><p>The logic underlying these playback options is implemented using Symbol.iterator. Let me quickly break down how each class works.</p><h4>Repeat</h4><p>Playing songs on repeat is the simplest task. With InfiniteArray, when we reach the end of the array we just go back to the first element, <em>ad infinitum</em>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4fd7e539fa22263d6972451dbd7ea18d/href">https://medium.com/media/4fd7e539fa22263d6972451dbd7ea18d/href</a></iframe><p><strong>Caution</strong>: InfiniteArray might be the simplest, but it is also the most dangerous! You can easily freeze a tab by calling [...infiniteArray].</p><p><strong>Shuffle</strong></p><p>Popular music services like <a href="https://www.independent.co.uk/life-style/gadgets-and-tech/news/why-random-shuffle-feels-far-from-random-10066621.html">Spotify used to shuffle songs</a> with the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates algorithm</a>, “but users complained that the playlist wasn’t genuinely random.”</p><p>Thankfully this is just an example, and Fisher-Yates is by far the simplest shuffling algorithm so we will go with that.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ddd4bbf2325265a490c2746c7cfe4d8a/href">https://medium.com/media/ddd4bbf2325265a490c2746c7cfe4d8a/href</a></iframe><p>While RandomArray does not modify the Array in place, we can use it to create a shuffled (randomly-sorted) copy of the original Array.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0a0f6ebf3acb0b6759459336ad34815c/href">https://medium.com/media/0a0f6ebf3acb0b6759459336ad34815c/href</a></iframe><p><strong>Note</strong>: The actual order will vary each time the spread operator is called.</p><p><strong>Repeat &amp; Shuffle</strong></p><p>Some users will enable both shuffle and repeat simultaneously. RandomInfiniteArray does just that, iterating both <em>randomly and infinitely.</em></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0d880f2c81cf3226e47620c89f3082e8/href">https://medium.com/media/0d880f2c81cf3226e47620c89f3082e8/href</a></iframe><p><strong>Caution</strong>:<strong> </strong>same warning as InfiniteArray, be careful looping infinitely!</p><p>Each of these classes can be used anywhere an Array is expected. In this example, updateIterator creates a shallow copy of the original album list with a type that depends on which playback options are selected.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d3a2f72574075a1c0053a5017bce344a/href">https://medium.com/media/d3a2f72574075a1c0053a5017bce344a/href</a></iframe><p>In a larger application, <strong>Symbol.iterator can cleanly encapsulate iteration behavior in classes or functions</strong>, decreasing code repetition and error risk.</p><h3>Break Free</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/419/1*_ktjofuKUE5wmpolBhkp7w.jpeg" /></figure><p>It is time to break free from the standard for loop! Thus far, I have shown how Symbol.iterator offers significant advantages by encapsulating iteration patterns for a single array. What about multiple arrays?</p><p>Looping over two arrays pairwise in Vanilla JS quickly litters code with [i], but because this is a common task libraries like Lodash come with a <a href="https://lodash.com/docs/4.17.11#zip">_.zip</a> function that combines multiple sequential collections into one collection.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8073f4117b9cddf9db3a5080dba28ebd/href">https://medium.com/media/8073f4117b9cddf9db3a5080dba28ebd/href</a></iframe><p>Using variadic arguments and Symbol.iterator, we can easily write our own version of zip that iterates over multiple arrays but <em>without needing to clone the entirety of each array</em>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2e81dbe9bf013074e0f9773c74f4df57/href">https://medium.com/media/2e81dbe9bf013074e0f9773c74f4df57/href</a></iframe><p>Now we have a modular and readable way to iterate over multiple arrays at the same time! Extending the previous example to include a third dimension:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6003f2b3623c012011ec7eac6559f3d8/href">https://medium.com/media/6003f2b3623c012011ec7eac6559f3d8/href</a></iframe><p>In terms of performance, it seems the <a href="https://jsperf.com/js-zip">Symbol.iterator version of </a><a href="https://jsperf.com/js-zip">zip is significantly faster</a> than the one that clones arrays, while the <a href="https://jsperf.com/for-vs-range">range example above is comparable</a> to a standard for loop.</p><p>Of course accurate, generalizable benchmarks are difficult and it is important to measure in performance-critical settings. But generally speaking, <strong>Symbol.iterator uses less memory and should be at least as fast, if not faster</strong>, than other approaches.</p><p>Yet another use of iterators, is to stop iterating!</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/689d321553fbc994917763b35f209d3a/href">https://medium.com/media/689d321553fbc994917763b35f209d3a/href</a></iframe><p>This is similar to <a href="https://lodash.com/docs/4.17.11#takeWhile">_.takeWhile</a>, although again it does not require cloning.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f71492e712ff46c3312dc9902e9932ab/href">https://medium.com/media/f71492e712ff46c3312dc9902e9932ab/href</a></iframe><h3>One Last Time</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*eaLv6PT5L0xSb29DOvRR0w.gif" /><figcaption>iOS “Invisible Ink” Messages</figcaption></figure><p>Let me end with one more example. In the world of Snapchat and ephemeral messaging, what if we could create an Array using <a href="https://en.wikipedia.org/wiki/Invisible_ink">invisible ink</a>?</p><p>Ok, not literally but you get the idea.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8c4644a188cc93e32fd3324907a3aa3c/href">https://medium.com/media/8c4644a188cc93e32fd3324907a3aa3c/href</a></iframe><p>That is what I call VanishingArray, an Array that removes elements as you loop through them. Iterate once, and <em>only</em> once.</p><p>Before you move on too fast, it should be noted that Symbol.iterator has its downsides and should probably not be the default approach to every problem.</p><p>For one, it is often more complicated and verbose than simply chaining a combination of Array.filter and Array.map. There are also other approaches with equal or better performance characteristics, like <a href="https://blog.jeremyfairbank.com/javascript/functional-javascript-streams-2/">data streams</a> and libraries like <a href="https://github.com/winterbe/sequency">Sequency</a>.</p><p>That said, <strong>Symbol.iterator is versatile and efficient</strong>, and I have only presented a small subset of its utility. MDN has examples using <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator">generators with </a><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator">Symbol.asyncIterator</a> (that’s right, asynchronous iterators!). If you are curious about the Symbol API more generally, Keith Cirkel has a great article on <a href="https://www.keithcirkel.co.uk/metaprogramming-in-es6-symbols/">Metaprogramming in ES6</a>.</p><p>If you found this helpful, say thank u before moving on to the next article 👏</p><p>And follow me on <a href="https://www.linkedin.com/in/tombarrasso">LinkedIn</a> · <a href="https://github.com/Tombarr">GitHub</a> · <a href="https://medium.com/@tbarrasso">Medium</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=aef9f09ff78" width="1" height="1" alt=""><hr><p><a href="https://medium.com/front-end-weekly/thank-u-symbol-iterator-next-aef9f09ff78">thank u, [Symbol.iterator].next</a> was originally published in <a href="https://medium.com/front-end-weekly">Frontend Weekly</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The first shall be last with JavaScript arrays]]></title>
            <link>https://medium.com/free-code-camp/the-first-shall-be-last-with-javascript-arrays-11172fe9c1e0?source=rss-784649f47696------2</link>
            <guid isPermaLink="false">https://medium.com/p/11172fe9c1e0</guid>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Thomas Barrasso]]></dc:creator>
            <pubDate>Thu, 28 Mar 2019 15:44:06 GMT</pubDate>
            <atom:updated>2019-05-15T23:51:15.088Z</atom:updated>
            <content:encoded><![CDATA[<h3>The first shall be last with Javascript arrays</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qpeU4geKupip-i6jxgxF9Q.jpeg" /><figcaption><a href="https://www.reddit.com/r/TheDepthsBelow/comments/6j1gj6/sea_salps_forming_a_strange_looking_chain_video/">Sea Salps</a> forming natural “arrays”</figcaption></figure><blockquote>So the last shall be [0], and the first [length — 1].</blockquote><blockquote>– Adapted from <a href="https://www.biblegateway.com/passage/?search=Matthew+20%3A16&amp;version=KJV">Matthew 20:16</a></blockquote><p>I’ll skip the Malthusian Catastrophe and get to it: arrays are one of the simplest and most important data structures. While terminal elements (first and last) are frequently accessed, Javascript provides no convenient property or method for doing so and using indices can be redundant and prone to side effects and <a href="https://en.wikipedia.org/wiki/Off-by-one_error">off-by-one errors</a>.</p><p>A lesser-known, <a href="https://github.com/keithamus/proposal-array-last">recent Javascript TC39 Proposal</a> offers solace in the form of two “new” properties: Array.lastItem &amp; Array.lastIndex.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*76m-CxmcYIqWbOpln0Za8g.png" /><figcaption><a href="https://twitter.com/codinghorror/status/506010907021828096?lang=en">Jeff Atwood @codinghorror</a></figcaption></figure><h3><strong>Javascript Arrays</strong></h3><p>In many programming languages including Javascript, arrays are zero-indexed. The terminal elements–first and last– are accessed via the [0] and [length — 1] indices, respectively. We owe this pleasure to a <a href="https://medium.com/@albertkoz/why-does-array-start-with-index-0-65ffc07cbce8">precedent set by C</a>, where an index represents an offset from the head of an array. That makes zero the first index because it <em>is</em> the array head. Also Dijkstra proclaimed “<a href="https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html">zero as a most natural number.</a>” So let it be written. So let it be done.</p><p>I suspect if you averaged access by index you would find that terminal elements are referenced most often. After all, arrays are commonly used to store a sorted collection and doing so places superlative elements (highest, lowest, oldest, newest, etc.) at the ends.</p><p>Unlike other scripting languages (say <a href="https://secure.php.net/manual/en/function.end.php">PHP</a> or <a href="https://hexdocs.pm/elixir/List.html#last/1">Elixir</a>), Javascript does not provide convenient access to terminal array elements. Consider a trivial example of swapping the last elements in two arrays:</p><pre>let faces = [&quot;😀&quot;, &quot;😉&quot;, &quot;🤑&quot;, &quot;😏&quot;, &quot;🐐&quot;];<br>let animals = [&quot;🐒&quot;, &quot;🐕&quot;, &quot;🐈&quot;, &quot;🐎&quot;, &quot;🙄&quot;];</pre><pre>let lastAnimal = animals[animals.length - 1];<br>animals[animals.length - 1] = faces[faces.length - 1];<br>faces[faces.length - 1] = lastAnimal;</pre><p>The swapping logic requires 2 arrays referenced 8 times in 3 lines! In real-world code, this can quickly become very repetitive and difficult for a human to parse (though it is perfectly readable for a machine).</p><p>What’s more, solely using indices, you cannot define an array and get the last element in the same expression. That might not seem important, but consider another example where the function, getLogins(), makes an asynchronous API call and returns a sorted array. Assuming we want the most recent login event at the end of the array:</p><pre>let lastLogin = async () =&gt; {<br>  let logins = await getLogins();<br>  return logins[logins.length - 1];<br>};</pre><p>Unless the length is fixed and known in advance, we <em>have</em> to assign the array to a local variable to access the last element. One common way to address this in languages like <a href="http://knowledgehills.com/python/negative-indexing-slicing-stepping-comparing-lists.htm">Python</a> and <a href="http://rubyquicktips.com/post/996814716/use-negative-array-indices">Ruby</a> is to use negative indices. Then [length - 1] can be shortened to [-1], removing the need for local reference.</p><p>I find -1 only marginally more readable than length — 1, and while it is possible to approximate <a href="https://h3manth.com/new/blog/2013/negative-array-index-in-javascript/">negative array indices in Javascript</a> with <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy">ES6 Proxy</a> or Array.slice(-1)[0], both come with <a href="https://jsperf.com/last-array-element2/14">significant performance implications</a> for what should otherwise constitute simple random access.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/971/1*Tv90DqFJ1xOyUhbtmm4UXw.png" /></figure><h4><strong>Underscore &amp; Lodash</strong></h4><p>One of the most well-known principles in software development is Don’t Repeat Yourself (DRY). Since accessing terminal elements is so common, why not write a helper function to do it? Fortunately, many libraries like <a href="https://underscorejs.org/">Underscore</a> and <a href="https://lodash.com/">Lodash</a> already provide utilities for _.first &amp; _.last.</p><p>This offers a big improvement in the lastLogin() example above:</p><pre>let lastLogin = async () =&gt; _.last(await getLogins());</pre><p>But when it comes to the example of swapping last elements, the improvement is less significant:</p><pre>let faces = [&quot;😀&quot;, &quot;😉&quot;, &quot;🤑&quot;, &quot;😏&quot;, &quot;🐐&quot;];<br>let animals = [&quot;🐒&quot;, &quot;🐕&quot;, &quot;🐈&quot;, &quot;🐎&quot;, &quot;🙄&quot;];</pre><pre>let lastAnimal = _.last(animals);<br>animals[animals.length - 1] = _.last(faces);<br>faces[faces.length - 1] = lastAnimal;</pre><p>These utility functions removed 2 of the 8 references, only now we introduced an external dependency that, oddly enough, does not include a function for <em>setting</em> terminal elements.</p><p>Most likely such a function is deliberately excluded because its API would be confusing and hard to readable. Early versions of Lodash provided a method <a href="https://github.com/lodash/lodash/issues/946">_.last(array, n)</a> where <em>n</em> was the number of items from the end but it was ultimately removed in favor of <a href="https://lodash.com/docs#take">_.take</a>(array, n).</p><p>Assuming nums is an array of numbers, what would be the expected behavior of _.last(nums, n)? It could return the last two elements like _.take, or it could set the value of the last element equal to <em>n</em>.</p><p>If we were to write a function for setting the last element in an array, there are only a few approaches to consider using pure functions, method chaining, or using prototype:</p><pre>let nums = [&#39;d&#39;, &#39;e&#39;, &#39;v&#39;, &#39;e&#39;, &#39;l&#39;]; // set first = last</pre><pre>_.first(faces, _.last(faces));        // Lodash style</pre><pre>$(faces).first($(faces).last());      // jQuery style</pre><pre>faces.first(faces.last());            // prototype</pre><p>I do not find any of these approaches to be much of an improvement. In fact, something important is lost here. Each performs an assignment, but none use the assignment operator (=).This could be made more apparent with naming conventions like getLast and setFirst, but that quickly becomes overly verbose. Not to mention the <a href="https://blog.toggl.com/seven-levels-developer-hell/">fifth circle of hell</a> is full of programmers forced to navigate “self-documenting” legacy code where the only way to access or modify data is through getters and setters.</p><p>Somehow, it looks like we are stuck with [0] &amp; [length — 1]…</p><p>Or are we? 😏</p><h4><strong>The Proposal</strong></h4><p>As mentioned, an ECMAScript Technical Candidate (TC39) proposal attempts to address this problem by defining two new properties on the Array object: lastItem &amp; lastIndex. This proposal is <a href="https://kangax.github.io/compat-table/esnext/">already supported</a> in <a href="https://github.com/zloirock/core-js">core-js 3</a> and usable today in Babel 7 &amp; TypeScript. Even if you are not using a transpiler, this proposal includes a <a href="https://github.com/keithamus/proposal-array-last#polyfill">polyfill</a>.</p><p>Personally, I do not find much value in lastIndex and prefer Ruby’s shorter naming for <a href="https://stackoverflow.com/questions/18212240/ruby-convention-for-accessing-first-last-element-in-array">first and </a><a href="https://stackoverflow.com/questions/18212240/ruby-convention-for-accessing-first-last-element-in-array">last</a>, although this was ruled out because of <a href="https://github.com/keithamus/proposal-array-last/issues/4">potential web compatibility issues</a>. I am also surprised that this proposal does not suggest a firstItem property for consistency and symmetry.</p><p>In the interim, I can offer a no-dependency, Ruby-esque approach in ES6:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f4568dce3f1305ee64c6565e2bdb6635/href">https://medium.com/media/f4568dce3f1305ee64c6565e2bdb6635/href</a></iframe><h4><strong>First &amp; Last</strong></h4><p>We now have two new Array properties–first &amp; last–and a solution that:</p><p>✓ Uses the assignment operator</p><p>✓ Does not clone the array</p><p>✓ Can define an array and get a terminal element in one expression</p><p>✓ Is human-readable</p><p>✓ Provides one interface for getting &amp; setting</p><p>We can rewrite lastLogin() again in a single line:</p><pre>let lastLogin = async () =&gt; (await getLogins()).last;</pre><p>But the real win comes when we swap the last elements in two arrays with half the number of references:</p><pre>let faces = [&quot;😀&quot;, &quot;😉&quot;, &quot;🤑&quot;, &quot;😏&quot;, &quot;🐐&quot;];<br>let animals = [&quot;🐒&quot;, &quot;🐕&quot;, &quot;🐈&quot;, &quot;🐎&quot;, &quot;🙄&quot;];</pre><pre>let lastAnimal = animals.last;<br>animals.last = faces.last;<br>faces.last = lastAnimal;</pre><p>Everything is perfect and we have solved one of CS’ most difficult problems. There are no evil covenants hiding in this approach…</p><h4><strong>Prototype Paranoia</strong></h4><blockquote>Surely there is no one [programmer] on earth so righteous as to do good without ever sinning.– Adapted from <a href="https://www.biblegateway.com/passage/?search=Ecclesiastes+7%3A20&amp;version=NRSVA">Ecclesiastes 7:20</a></blockquote><p>Many consider <a href="https://we-are.bookmyshow.com/prototype-pattern-in-js-5c1f44440081">extending a native Object’s prototype an anti-pattern</a> and a crime punishable by 100 years of programming in Java. Prior to the introduction of the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties">enumerable</a> property, <a href="https://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/">extending </a><a href="https://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/">Object.prototype</a> could change the behavior of for in loops. It could also lead to conflict between various libraries, frameworks, and third-party dependencies.</p><p>Perhaps the most insidious issue is that, without compile-time tools, a simple spelling mistake could <a href="https://nemisj.com/why-getterssetters-is-a-bad-idea-in-javascript/">inadvertently create an associative array</a>.</p><pre>let faces = [&quot;😀&quot;, &quot;😉&quot;, &quot;🤑&quot;, &quot;😏&quot;, &quot;🐐&quot;];<br>let ln = faces.length</pre><pre>faces.lst = &quot;🙄&quot;; // (5) [&quot;😀&quot;, &quot;😉&quot;, &quot;🤑&quot;, &quot;😏&quot;, &quot;🐐&quot;, lst: &quot;🙄&quot;]</pre><pre>faces.lst(&quot;🙄&quot;);  // Uncaught TypeError: faces.lst is not a function</pre><pre>faces[ln] = &quot;🙄&quot;; // (6) [&quot;😀&quot;, &quot;😉&quot;, &quot;🤑&quot;, &quot;😏&quot;, &quot;🐐&quot;, &quot;🙄&quot;]</pre><p>This concern is not unique to our approach, it applies to all native Object prototypes (including arrays). Yet this offers safety in a different form. Arrays in Javascript are not fixed in length and consequently, there are no IndexOutOfBoundsExceptions. Using Array.last ensures we do not accidentally try to access [length] and unintentionally enter undefined territory.</p><p>No matter which approach you take, there are pitfalls. Once again, software proves to be an <a href="https://pragprog.com/articles/the-art-of-tradeoffs">art of making tradeoffs</a>.</p><p>Continuing with the extraneous biblical reference, assuming we do not believe extending Array.prototype is an eternal sin, or we’re willing to take a bite of the forbidden fruit, we can use this concise and readable syntax today!</p><h3><strong>Last Words</strong></h3><blockquote>Programs must be written for people to read, and only incidentally for machines to execute. – <a href="https://www.goodreads.com/book/show/43713.Structure_and_Interpretation_of_Computer_Programs?from_choice=false&amp;from_home_module=false">Harold Abelson</a></blockquote><p>In scripting languages like Javascript, I prefer code that is functional, concise, and readable. When it comes to accessing terminal array elements, I find the Array.last property to be the most elegant. In a production front-end application, I might favor Lodash to minimize conflict and cross-browser concerns. But in Node back-end services where I control the environment, I prefer these custom properties.</p><p>I am certainly <a href="https://esdiscuss.org/topic/array-prototype-last">not the first</a>, nor will I be the last, to appreciate the value (or caution about the implications) of properties like Array.lastItem, which is hopefully coming soon to a version of ECMAScript near you.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Z63EqxzV68XKUa3b81d8wg.png" /></figure><p>Follow me on <a href="https://www.linkedin.com/in/tombarrasso">LinkedIn</a> · <a href="https://github.com/Tombarr">GitHub</a> · <a href="https://medium.com/@tbarrasso">Medium</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=11172fe9c1e0" width="1" height="1" alt=""><hr><p><a href="https://medium.com/free-code-camp/the-first-shall-be-last-with-javascript-arrays-11172fe9c1e0">The first shall be last with JavaScript arrays</a> was originally published in <a href="https://medium.com/free-code-camp">We’ve moved to freeCodeCamp.org/news</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>