<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Oleg Gromov</title>
    <description>The latest articles on DEV Community by Oleg Gromov (@oleggromov).</description>
    <link>https://dev.to/oleggromov</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F22664%2F5af40926-144b-461f-918e-26a943a5a3d0.png</url>
      <title>DEV Community: Oleg Gromov</title>
      <link>https://dev.to/oleggromov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oleggromov"/>
    <language>en</language>
    <item>
      <title>How Much is a Year of Your Life?</title>
      <dc:creator>Oleg Gromov</dc:creator>
      <pubDate>Mon, 29 Aug 2022 22:44:03 +0000</pubDate>
      <link>https://dev.to/oleggromov/how-much-is-a-year-of-your-life-3pl9</link>
      <guid>https://dev.to/oleggromov/how-much-is-a-year-of-your-life-3pl9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Hello amazing dev.to community!&lt;/p&gt;

&lt;p&gt;A disclaimer: this is an article cross-posted from &lt;a href="https://gromov.com/en/how-much-is-year-of-your-life"&gt;my website&lt;/a&gt;. Posting it here for a broader discussion and, hopefully, some insights for you as well.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Oleg&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It must be priceless, right? So thought I, until I realised I've been putting money first for over a decade.&lt;/p&gt;

&lt;p&gt;In 2022, a year of my life is &lt;code&gt;$200k&lt;/code&gt;. It was about &lt;code&gt;$110k&lt;/code&gt; in 2021, &lt;code&gt;$175k&lt;/code&gt; in 2020, &lt;code&gt;$90k&lt;/code&gt; in 2019.&lt;/p&gt;

&lt;p&gt;Here's a brief story of my life 👇&lt;/p&gt;

&lt;h2&gt;
  
  
  Everything starts with the family
&lt;/h2&gt;

&lt;p&gt;I am from a poor one. When I was young, we had troubles buying clothes, I never had a nice computer to play latest games. We had enough food but god knows what my parents did for that!&lt;/p&gt;

&lt;p&gt;I don't blame them. But it's certainly shaped my perception.&lt;/p&gt;

&lt;p&gt;I started earning at 14 as a "computer master".&lt;/p&gt;

&lt;p&gt;I helped people with hardware and software issues, advertising my services in a local free newspaper.&lt;/p&gt;

&lt;p&gt;Not because I loved it but because I wanted to escape poverty.&lt;/p&gt;

&lt;p&gt;I did not. But I kept trying.&lt;/p&gt;

&lt;h2&gt;
  
  
  I started climbing the company ladder
&lt;/h2&gt;

&lt;p&gt;As a web developer, I worked for an outsourcing firm, a game company, finally Yandex.&lt;/p&gt;

&lt;p&gt;I don't call it "career" ladder because I wasn't actually pursuing a career. I was pursuing money.&lt;/p&gt;

&lt;p&gt;Then Klarna, Toptal, Facebook, Hook, now Sourcegraph.&lt;/p&gt;

&lt;h2&gt;
  
  
  Each year or two, my income had increased
&lt;/h2&gt;

&lt;p&gt;And it became very natural to expect it to keep growing.&lt;/p&gt;

&lt;p&gt;But after 3 years at Yandex, I quit my job. And went to study in the US for 6 months!&lt;/p&gt;

&lt;p&gt;Even though I rationalised this decision, it was partly emotional too.&lt;/p&gt;

&lt;p&gt;I decided to go to the US to improve my English so that I could continue my career abroad.&lt;/p&gt;

&lt;p&gt;That's on the conscious level. But I also felt that something wasn't right.&lt;/p&gt;

&lt;p&gt;I didn't necessarily want more of what I already had. I wanted something different.&lt;/p&gt;

&lt;h2&gt;
  
  
  But I kept chasing money
&lt;/h2&gt;

&lt;p&gt;I had already solved the most pressing problems. I had enough food, a nice flat, a car. I could afford traveling.&lt;/p&gt;

&lt;p&gt;But the momentum of the habit was so high that I couldn't stop.&lt;/p&gt;

&lt;p&gt;This was 5 years ago. But only this year I realised this was a habit.&lt;/p&gt;

&lt;h2&gt;
  
  
  A habit that grew in my childhood
&lt;/h2&gt;

&lt;p&gt;When I didn't have enough essentials. I was poor and I was embarassed.&lt;/p&gt;

&lt;p&gt;What the habit of chasing money was supposed to solve, had been already solved long ago!&lt;/p&gt;

&lt;p&gt;And I began thinking about my life in general. I started looking into the future.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What do I want?&lt;/li&gt;
&lt;li&gt;Why?&lt;/li&gt;
&lt;li&gt;How?&lt;/li&gt;
&lt;li&gt;With whom?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lots of questions like that. And I don't have most of the answers yet.&lt;/p&gt;

&lt;p&gt;But I know for sure that time is more valuable than money once the existential threats are figured out.&lt;/p&gt;

&lt;p&gt;It's still valuable, of course, and can buy me lots of freedoms.&lt;/p&gt;

&lt;h2&gt;
  
  
  But I no longer can go only on money
&lt;/h2&gt;

&lt;p&gt;I want to use my life wisely. Explore, have fun, try things on my own. Have an adventure. Decide what's the next turn.&lt;/p&gt;

&lt;p&gt;Having a career and building a business used to seem incompatible to me. But juxtaposing them doesn't make any sense!&lt;/p&gt;

&lt;p&gt;There's plenty of happy people that are employed.&lt;/p&gt;

&lt;p&gt;There must be even more entrepreneurs who struggle.&lt;/p&gt;

&lt;p&gt;And even though I had my first business idea probably around 15 years ago, the shape of what I do just cannot be the answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the answer then?
&lt;/h2&gt;

&lt;p&gt;Well, I don't know. But I am setting off to find out.&lt;/p&gt;

&lt;p&gt;What I definitely know that once you've solved your physiological and safety needs, time becomes infinitely more valuable than money.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is probably the most personal thing I have ever posted on internet. Thank you for reading! 🤩&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;And what's your take on the money vs time problem?&lt;/em&gt;&lt;/p&gt;

</description>
      <category>hiring</category>
      <category>career</category>
      <category>webdev</category>
      <category>salary</category>
    </item>
    <item>
      <title>How to use bitwise operations to compactly store small values in a single number</title>
      <dc:creator>Oleg Gromov</dc:creator>
      <pubDate>Fri, 14 May 2021 12:08:23 +0000</pubDate>
      <link>https://dev.to/oleggromov/how-to-use-bitwise-operations-to-compactly-store-small-values-in-a-single-number-3nb7</link>
      <guid>https://dev.to/oleggromov/how-to-use-bitwise-operations-to-compactly-store-small-values-in-a-single-number-3nb7</guid>
      <description>&lt;p&gt;Computer science is full of magic, which is often obscured from our eyes these high-level days. And rightly so: usually to implement features needed by our users we don't need any fancy CS knowledge.&lt;/p&gt;

&lt;p&gt;Yet sometimes you may get something from knowing basics of computer science, such as bitwise operations and binary code in general.&lt;/p&gt;

&lt;p&gt;I won't go into much detail about how decimal, binary and other numeral systems work. Instead, I'll show you how to &lt;strong&gt;compactly store small values&lt;/strong&gt; needed by our web applications in a single 32-bit unsigned integer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;32 bits as a cap aren't selected randomly. This is the limit for a JS interpeter to perform binary operations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why store something in a compact form?
&lt;/h2&gt;

&lt;p&gt;Let's start with a typical single page web application. For instance, a spreadsheet editing app with multiple panels and windows sprinkled all over the screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fay0pmronmws0vdjiy548.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fay0pmronmws0vdjiy548.png" alt="Spreadsheet App with Panels"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will also assume our users may benefit from sharing links to the documents they create &lt;em&gt;and&lt;/em&gt; restoring exact UI configuration so that it's easier to resume work from the state we left it off at.&lt;/p&gt;

&lt;p&gt;So our app has 10 panels, and we need to encode state of these panels (open or closed for simplicity) in URLs they share.&lt;/p&gt;

&lt;p&gt;You typically would create a URL similar to this: &lt;code&gt;?panel1=on&amp;amp;panel2=off&amp;amp;panel3=on&lt;/code&gt; and so on. It's easy to see how wordy this becomes even with 10 panels, and what if other parts of our URLs are important too? So we don't want to end up sharing something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx4bkv0i8yesks59cwp2q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx4bkv0i8yesks59cwp2q.png" alt="Ridiculous URL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What if instead, we could use a single URL parameter, say &lt;code&gt;?panels=626&lt;/code&gt; to encode all these values at once, in a single number?&lt;/p&gt;

&lt;p&gt;This is possible, thanks to the bitwise operations magic, and I'll show you how exactly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basics of bitwise operations
&lt;/h2&gt;

&lt;p&gt;If you paste &lt;code&gt;parseInt('1001110010', 2)&lt;/code&gt; into a JavaScript interpeter prompt and hit enter, you'll see the decimal number - &lt;code&gt;626&lt;/code&gt;. This is how these &lt;em&gt;10 bits&lt;/em&gt; are encoded into a numeric value in decimal numeral system.&lt;/p&gt;

&lt;p&gt;By definition, a bit is a value represented by two possible states - 1 and 0. Exactly what we need to encode a &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt; in the most compact form. So we can use these mechanics to store panel states (visible or hidden)!&lt;/p&gt;

&lt;p&gt;Let's try doing so by hand.&lt;/p&gt;

&lt;p&gt;We will count bits from right to left, first bit having the index of &lt;code&gt;0&lt;/code&gt; and last having &lt;code&gt;9&lt;/code&gt;. These are, not coincidentally, powers to which you have to raise the binary base &lt;code&gt;2^n&lt;/code&gt; or &lt;code&gt;Math.pow(2, n)&lt;/code&gt; to get numbers represented by these bits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using exponentiation and binary shifts to store and restore values
&lt;/h3&gt;

&lt;p&gt;So to store the state of panels, we may use the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;panelStates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;panelStates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;panelStates&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;bit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may paste the code above into any JS interpreter and see that this code, indeed, prints the expected number &lt;code&gt;626&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But why? In the loop, we applied the binary &lt;code&gt;OR&lt;/code&gt; operation represented in JavaScript by the pipe sign &lt;code&gt;|&lt;/code&gt; to the &lt;code&gt;result&lt;/code&gt;. As the second operand, we used 2 raised to the power of &lt;code&gt;index&lt;/code&gt;, which is, not coincidentally, the number of bit when counting from right to left, starting from zero.&lt;/p&gt;

&lt;p&gt;Magic? No, it's binary encoding in all its beauty.&lt;/p&gt;

&lt;p&gt;But hey, you should say now, we don't need to only to encode, we need to get our values back too! Let's do so.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;panelStatesEncoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;626&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;panelStates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;panelStatesEncoded&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bitValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mask&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;panelStates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bitValue&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;panelStates&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the last line of this code will expectedly print an array with the same values we started from.&lt;/p&gt;

&lt;p&gt;Why? Well, this code includes a few more binary operations we have to understand. But there is nothing impossible for a computer science magician, isn't it?&lt;/p&gt;

&lt;p&gt;First, we start with looping from 0 to 9, inclusive, as we know exactly how many boolean values we're looking for in a number.&lt;/p&gt;

&lt;p&gt;The operation we need to perform next is &lt;em&gt;binary masking&lt;/em&gt; using a logical &lt;code&gt;AND&lt;/code&gt; operator represented by &lt;code&gt;&amp;amp;&lt;/code&gt; in JavaScript. So we know that a particular bit in our &lt;code&gt;panelStatesEncoded&lt;/code&gt; number represents state of an N-th panel. Therefore, we need to somehow choose it and only it.&lt;/p&gt;

&lt;p&gt;This is done by the &lt;code&gt;AND&lt;/code&gt; operator: when we do &lt;code&gt;Math.pow(2, 3)&lt;/code&gt; for the 3rd panel state, for example, we get 8, which is &lt;code&gt;1000&lt;/code&gt; in binary code. &lt;code&gt;1000 &amp;amp; 1011&lt;/code&gt;, where the first number is a mask and the second one is our encoded panels state's first 4 bits, we get &lt;code&gt;1000&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is because logical &lt;code&gt;AND&lt;/code&gt; only leaves the bits that are present in both values on. Had we used &lt;code&gt;0011&lt;/code&gt; as our second operand, AND would yield &lt;code&gt;0000&lt;/code&gt;, which is simply &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But then &lt;code&gt;1000&lt;/code&gt; we get from the operation is 8, not &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;, or anything else meaningful. So we have to &lt;em&gt;shift it to the right&lt;/em&gt; using binary shift operator &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; 3 times (our index, the power of 2 that is 8) to get a single bit.&lt;/p&gt;

&lt;p&gt;A single bit, a 0 or 1, is easily converted into a boolean value using the &lt;code&gt;Boolean&lt;/code&gt; conversion, and we can push it to the array of values.&lt;/p&gt;

&lt;p&gt;Our puzzle is now complete. We can toggle right bits by doing &lt;code&gt;Math.pow(2, n)&lt;/code&gt; or actually simply doing binary shift to the left &lt;code&gt;1 &amp;lt;&amp;lt; n&lt;/code&gt;, which is the exact equivalent of raising 2 to the power of &lt;code&gt;n&lt;/code&gt;. Then we can decode, applying a &lt;em&gt;bitmask&lt;/em&gt; and shifting it back to the right &lt;code&gt;n&lt;/code&gt; times.&lt;/p&gt;

&lt;h2&gt;
  
  
  Abstracting complexity away
&lt;/h2&gt;

&lt;p&gt;Hopefully at this point you're as much thrilled as I am. Even decades after getting into computers, I am still excited to make them do what I want speaking the same language they do. The almighty binary.&lt;/p&gt;

&lt;p&gt;But isn't it too tedious to write by hand and, perhaps, even too error-prone and complicated to be used in production-ready applications?&lt;/p&gt;

&lt;p&gt;Indeed, it is! So I created a library to abstract unnecessary complexity away (yet I'd still argue you have to know how it works under the hood). Make some noise for &lt;a href="https://github.com/oleggromov/bitwise-options" rel="noopener noreferrer"&gt;&lt;code&gt;bitwise-options&lt;/code&gt;&lt;/a&gt;. Yay!&lt;/p&gt;

&lt;p&gt;Not only does it allow you name your options and then read them from and write to a single 32-bit integer, it also makes it possible to store multiple &lt;em&gt;unsigned&lt;/em&gt; integer values in a single number.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;BitwiseOptions&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bitwise-options&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Configure available options&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BitwiseOptions&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// single-bit boolean by default&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;uint_single&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;uint&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// single-bit unsigned int&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;uint_3bit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;uint&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// 3-bit unsigned integer in range of [0, 7]&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 11010 in binary&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
  &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;uint_single&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
  &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;uint_3bit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// 6&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;uint_3bit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;uint_3bit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toNumber&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find the library on &lt;a href="https://github.com/oleggromov/bitwise-options" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and &lt;a href="https://www.npmjs.com/package/bitwise-options" rel="noopener noreferrer"&gt;npm&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Yes, I was too lazy to implement signed integer support but will be happy to do so if you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;enjoyed reading the article as much as I enjoyed writing it&lt;/li&gt;
&lt;li&gt;give the library a star on github so that more people get to know about it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://twitter.com/oleggromov" rel="noopener noreferrer"&gt;follow me on Twitter&lt;/a&gt;&lt;/strong&gt;, where I write about things worth knowing as a software person if you seek independence and satisfaction &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you for you attention and let me know in the comments if you found this useful and why?&lt;/p&gt;

</description>
      <category>binary</category>
      <category>bitwise</category>
      <category>boolean</category>
      <category>javascript</category>
    </item>
    <item>
      <title>The simplest and most detailed CSS flex-box layout tutorial</title>
      <dc:creator>Oleg Gromov</dc:creator>
      <pubDate>Wed, 20 Jan 2021 22:45:15 +0000</pubDate>
      <link>https://dev.to/oleggromov/the-simplest-and-most-detailed-css-flex-box-layout-tutorial-312e</link>
      <guid>https://dev.to/oleggromov/the-simplest-and-most-detailed-css-flex-box-layout-tutorial-312e</guid>
      <description>&lt;p&gt;Hi folks,&lt;br&gt;
Hope you find this small tutorial useful.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am now working on a web app prototype and need a panel-like full-screen layout for it. &lt;br&gt;&lt;br&gt;My first intention was to look into React component libraries but that's actually an overkill.&lt;br&gt;&lt;br&gt;Let's see how to create a simple layout like that with pure CSS and flex-box.&lt;br&gt;&lt;br&gt;1/ &lt;a href="https://t.co/agTGAX1dmr"&gt;pic.twitter.com/agTGAX1dmr&lt;/a&gt;&lt;/p&gt;— Oleg GROMOV (&lt;a class="mentioned-user" href="https://dev.to/oleggromov"&gt;@oleggromov&lt;/a&gt;) &lt;a href="https://twitter.com/oleggromov/status/1352015700982980608?ref_src=twsrc%5Etfw"&gt;January 20, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;First, let's do basic HTML. We'll keep it as simple as possible and also use semantic HTML5 elements.&lt;br&gt;&lt;br&gt;Although completely irrelevant when you make a web app and not a content site to be indexed by search engines, it's still good practice to add semantics to your markup.&lt;br&gt;&lt;br&gt;2/ &lt;a href="https://t.co/VsqVxjM6uF"&gt;pic.twitter.com/VsqVxjM6uF&lt;/a&gt;&lt;/p&gt;— Oleg GROMOV (&lt;a class="mentioned-user" href="https://dev.to/oleggromov"&gt;@oleggromov&lt;/a&gt;) &lt;a href="https://twitter.com/oleggromov/status/1352015707001806854?ref_src=twsrc%5Etfw"&gt;January 20, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;Let's go over the need for each element.&lt;br&gt;&lt;br&gt;Layout is needed to fill viewport vertically.&lt;br&gt;&lt;br&gt;&amp;lt;header&amp;gt; and &amp;lt;main&amp;gt; designate corresponding layout areas.&lt;br&gt;&lt;br&gt;&amp;lt;aside&amp;gt; and &amp;lt;section&amp;gt;s all mean columns, although aside gets additional touch of exclusivity.&lt;br&gt;&lt;br&gt;Ignore contents though 😜&lt;br&gt;&lt;br&gt;3/&lt;/p&gt;— Oleg GROMOV (&lt;a class="mentioned-user" href="https://dev.to/oleggromov"&gt;@oleggromov&lt;/a&gt;) &lt;a href="https://twitter.com/oleggromov/status/1352015709262532611?ref_src=twsrc%5Etfw"&gt;January 20, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;With only background styling it looks something like this.&lt;br&gt;&lt;br&gt;Let's continue with CSS step-by-step.&lt;br&gt;&lt;br&gt;4/ &lt;a href="https://t.co/5OpAsBFYhS"&gt;pic.twitter.com/5OpAsBFYhS&lt;/a&gt;&lt;/p&gt;— Oleg GROMOV (&lt;a class="mentioned-user" href="https://dev.to/oleggromov"&gt;@oleggromov&lt;/a&gt;) &lt;a href="https://twitter.com/oleggromov/status/1352015711795900420?ref_src=twsrc%5Etfw"&gt;January 20, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;We need to stretch our outermost body and html elements to 100% of height initially with the according property . Note that it won't make elements cut content if you go over the height limit. &lt;br&gt;&lt;br&gt;Also let's set margin: 0 so that we don't have any annoying paddings at the edges.&lt;br&gt;&lt;br&gt;5/ &lt;a href="https://t.co/0VBQSdAhWP"&gt;pic.twitter.com/0VBQSdAhWP&lt;/a&gt;&lt;/p&gt;— Oleg GROMOV (&lt;a class="mentioned-user" href="https://dev.to/oleggromov"&gt;@oleggromov&lt;/a&gt;) &lt;a href="https://twitter.com/oleggromov/status/1352015716887752708?ref_src=twsrc%5Etfw"&gt;January 20, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;Now let's nudge our div.layout into being a good container for the future columns.&lt;br&gt;&lt;br&gt;For that, we'll make it display: flex, set flex-direction and 100% height. &lt;br&gt;&lt;br&gt;You see that the annoying green flooded entire screen, meaning that layout has stretched but not the columns yet. &lt;br&gt;&lt;br&gt;6/ &lt;a href="https://t.co/a7FsYYyA1m"&gt;pic.twitter.com/a7FsYYyA1m&lt;/a&gt;&lt;/p&gt;— Oleg GROMOV (&lt;a class="mentioned-user" href="https://dev.to/oleggromov"&gt;@oleggromov&lt;/a&gt;) &lt;a href="https://twitter.com/oleggromov/status/1352015719655825411?ref_src=twsrc%5Etfw"&gt;January 20, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;Remember `panel` classes I set to header, aside, and section-s? This was no mistake. Panel is an important UI concept I want to have in my vocabulary. Let's make all panels have equal padding of 12px.&lt;br&gt;&lt;br&gt;It's not the best for a11y to use pixels, but we're playing here, right?&lt;br&gt;&lt;br&gt;7/ &lt;a href="https://t.co/cLxjstP2m2"&gt;pic.twitter.com/cLxjstP2m2&lt;/a&gt;&lt;/p&gt;— Oleg GROMOV (&lt;a class="mentioned-user" href="https://dev.to/oleggromov"&gt;@oleggromov&lt;/a&gt;) &lt;a href="https://twitter.com/oleggromov/status/1352015727839096832?ref_src=twsrc%5Etfw"&gt;January 20, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;Next let's make them stretch. For that, we need to add `flex: 1` rule to .panel. It's a shorthand, check out this tutorial to learn more &lt;a href="https://t.co/LaFqABmLlU"&gt;https://t.co/LaFqABmLlU&lt;/a&gt;&lt;br&gt;&lt;br&gt;Meanwhile, panels stretched to fill the screen but not in the way I wanted. Fixing it next step.&lt;br&gt;&lt;br&gt;8/ &lt;a href="https://t.co/L9dT2YhkIR"&gt;pic.twitter.com/L9dT2YhkIR&lt;/a&gt;&lt;/p&gt;— Oleg GROMOV (&lt;a class="mentioned-user" href="https://dev.to/oleggromov"&gt;@oleggromov&lt;/a&gt;) &lt;a href="https://twitter.com/oleggromov/status/1352015733610450944?ref_src=twsrc%5Etfw"&gt;January 20, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;There's flex-grow and flex-shrink in addition to usual width, min-, and max-width properties to control size of flex-ed boxes.&lt;br&gt;&lt;br&gt;Using flex-grow (its shorthand flex) and setting .columns { flex: 100 } we make them attempt take 100x more space than another flex child. &lt;br&gt;&lt;br&gt;9/&lt;/p&gt;— Oleg GROMOV (&lt;a class="mentioned-user" href="https://dev.to/oleggromov"&gt;@oleggromov&lt;/a&gt;) &lt;a href="https://twitter.com/oleggromov/status/1352015736294813701?ref_src=twsrc%5Etfw"&gt;January 20, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;Another child, &amp;lt;header&amp;gt;, inherited its flex: 1 from .panel that I conveniently set in one of the previous steps. &lt;br&gt;&lt;br&gt;At this point we have almost entirely working layout without one simple thing: width restriction for the aside.&lt;br&gt;&lt;br&gt;To have it, let's add max-width: 16em to it.&lt;br&gt;&lt;br&gt;10/ &lt;a href="https://t.co/fovYEft1R7"&gt;pic.twitter.com/fovYEft1R7&lt;/a&gt;&lt;/p&gt;— Oleg GROMOV (&lt;a class="mentioned-user" href="https://dev.to/oleggromov"&gt;@oleggromov&lt;/a&gt;) &lt;a href="https://twitter.com/oleggromov/status/1352015741382496257?ref_src=twsrc%5Etfw"&gt;January 20, 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;blockquote data-conversation="none"&gt;
&lt;p&gt;So now we have a layout that:&lt;br&gt;- fills entire viewport &lt;br&gt;- accommodates as many columns as needed&lt;br&gt;- is super simple, pure CSS&lt;br&gt;&lt;br&gt;You can grab the code and play with it here: &lt;a href="https://t.co/O4W1CxuBEO"&gt;https://t.co/O4W1CxuBEO&lt;/a&gt;&lt;br&gt;&lt;br&gt;Was this useful? Let me know in comments. Good luck hacking your CSS! 🤘&lt;br&gt;&lt;br&gt;11/ &lt;a href="https://t.co/dxkrRNDQ1k"&gt;pic.twitter.com/dxkrRNDQ1k&lt;/a&gt;&lt;/p&gt;— Oleg GROMOV (&lt;a class="mentioned-user" href="https://dev.to/oleggromov"&gt;@oleggromov&lt;/a&gt;) &lt;a href="https://twitter.com/oleggromov/status/1352015803160391684?ref_src=twsrc%5Etfw"&gt;January 20, 2021&lt;/a&gt;
&lt;/blockquote&gt;

</description>
      <category>css</category>
      <category>flexbox</category>
      <category>layout</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Refactoring is not Rewriting Code</title>
      <dc:creator>Oleg Gromov</dc:creator>
      <pubDate>Tue, 17 Sep 2019 09:10:33 +0000</pubDate>
      <link>https://dev.to/oleggromov/refactoring-is-not-rewriting-code-2lma</link>
      <guid>https://dev.to/oleggromov/refactoring-is-not-rewriting-code-2lma</guid>
      <description>&lt;p&gt;Hello, folks,&lt;/p&gt;

&lt;p&gt;How do you distinguish between &lt;em&gt;refactoring&lt;/em&gt; and &lt;em&gt;rewriting&lt;/em&gt; code? &lt;/p&gt;

&lt;p&gt;Would you usually refactor code because you have to implement a new feature or just because &lt;em&gt;it smells&lt;/em&gt;? &lt;/p&gt;

&lt;p&gt;What's your justification for spending time on refactorings for those who prioritize, be it your engineering manager or PM? &lt;/p&gt;

&lt;p&gt;I have made my short notes about &lt;a href="https://oleggromov.com/refactoring-vs-rewriting-code?utm_source=devto"&gt;Refactoring vs Rewriting&lt;/a&gt; but I would love you to share your experience, too. &lt;/p&gt;

</description>
      <category>discuss</category>
      <category>programming</category>
      <category>tips</category>
      <category>advice</category>
    </item>
    <item>
      <title>Understand What You Want</title>
      <dc:creator>Oleg Gromov</dc:creator>
      <pubDate>Wed, 11 Sep 2019 19:14:12 +0000</pubDate>
      <link>https://dev.to/oleggromov/understand-what-you-want-b3</link>
      <guid>https://dev.to/oleggromov/understand-what-you-want-b3</guid>
      <description>&lt;p&gt;Hello, the amazing Dev.to community member,&lt;/p&gt;

&lt;p&gt;Whether you’re a seasoned software engineer or just an aspiring developer, every time you engage with some project, you make a decision. A decision to dedicate your precious time and attention to something. It may be that you’ve barely thought of this or spent hours joggling those thoughts, as I have. &lt;/p&gt;

&lt;p&gt;Anyways, any decision to spend your time on something entails an implicit decision to give up on something else. Opportunity costs, as the economic theory names it. &lt;/p&gt;

&lt;p&gt;Either you start contributing to another open-source project, or assume a promotion at work, or anything else like pursuing a degree or dedicating more attention to your health, you implicitly decide to abandon, at least temporarily, something else. &lt;/p&gt;

&lt;p&gt;And there’s nothing wrong with the fact.&lt;/p&gt;

&lt;p&gt;What may be wrong, though, is if you make decisions like that based not upon your true values, principles, and objectives but upon something that just casually captured your attention. &lt;/p&gt;

&lt;p&gt;On memes floating around, similar to “Launch a startup to get free from office routine” or “Pick up a remote work to travel”. On psychology complexes that may originate in your childhood. Or on purely material motivation like getting a raise for performing better at work.&lt;/p&gt;

&lt;p&gt;These things, of completely different nature each, together with other stimuli form our behavior and drive our decisions. And ultimately define who we are and how proud we are of what we're doing and have done so far.&lt;/p&gt;

&lt;p&gt;For me, having achieved something I’m proud of and being a person I would admire myself, is important. For you, something else may be important. &lt;/p&gt;

&lt;p&gt;Despite this possibly huge difference, I truly believe each of us shall be conscious and skeptical enough when it comes to deciding what to do. How to spend our time. How to live the life.&lt;/p&gt;

&lt;p&gt;If that subject resonates with you, please take a look at my approach to How to &lt;a href="https://oleggromov.com/understand-what-you-want"&gt;understand what you want&lt;/a&gt;, where I cover things listed below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introspecting into your past.&lt;/li&gt;
&lt;li&gt;Taking small steps from where you are.&lt;/li&gt;
&lt;li&gt;Discarding shallow and embracing helpful memes.&lt;/li&gt;
&lt;li&gt;Getting inspired by the right examples.&lt;/li&gt;
&lt;li&gt;Establishing a healthy examination routine of your values and progress.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In case you find the approach I describe to be controversial, please also share your experience and thoughts. I hope to get a good discussion around this. And thanks for reading up to this point 🤘&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>mentalhealth</category>
      <category>psychology</category>
      <category>motivation</category>
    </item>
    <item>
      <title>Treeker - fake JSX generator 🤖</title>
      <dc:creator>Oleg Gromov</dc:creator>
      <pubDate>Mon, 29 Oct 2018 22:42:48 +0000</pubDate>
      <link>https://dev.to/oleggromov/treeker---fake-jsx-generator---1160</link>
      <guid>https://dev.to/oleggromov/treeker---fake-jsx-generator---1160</guid>
      <description>&lt;p&gt;Hi guys!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Have you ever wanted to generate a fake yet looking like real JSX tree for some testing purposes?&lt;/p&gt;

&lt;p&gt;I faced the issue when I decided to work on a server-side renderer that works with React and understood that I need some fake components with either deep nesting or large number of children. Quick look-up on the internet yielded nothing so I decided to create a simple tool on my own.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0FpyTVDq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://image.ibb.co/koq58L/treeker.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0FpyTVDq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://image.ibb.co/koq58L/treeker.gif" alt="Treeker usage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's easy to install, that is simply &lt;code&gt;yarn global add treeker&lt;/code&gt; or &lt;code&gt;npm i -g treeker&lt;/code&gt;, and easy to use. Please check with the readme in &lt;a href="https://github.com/oleggromov/treeker"&gt;oleggromov/treeker&lt;/a&gt; repo. &lt;/p&gt;

&lt;p&gt;And in case it helps you and/or you like the idea, give me a 👍 here r a ⭐️ on github and share your thoughts here in the comments. &lt;/p&gt;

&lt;p&gt;Thanks for your time 🙏&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>showdev</category>
      <category>react</category>
      <category>testing</category>
    </item>
    <item>
      <title>Observing Style Changes 👁</title>
      <dc:creator>Oleg Gromov</dc:creator>
      <pubDate>Sat, 24 Feb 2018 16:12:08 +0000</pubDate>
      <link>https://dev.to/oleggromov/observing-style-changes---d4f</link>
      <guid>https://dev.to/oleggromov/observing-style-changes---d4f</guid>
      <description>&lt;p&gt;While working on one of my inspirational OSS projects, I found out that there's currently no way to observe element style changes. At least I couldn't find any mentions of library-like solutions for that. I assume that the reason for that might be the fact it's hard to understand whether or not the styles have changed.&lt;/p&gt;

&lt;p&gt;So, I decided to write my own library and called it &lt;code&gt;SauronStyle&lt;/code&gt;. Please take a look and &lt;a href="https://github.com/oleggromov/sauron-style"&gt;give it a try&lt;/a&gt; if you need anything like that for your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Observe
&lt;/h2&gt;

&lt;p&gt;Leaving the &lt;em&gt;why?&lt;/em&gt; behind the scene, let's jump right to &lt;em&gt;how&lt;/em&gt;. There're a few ways to update element styling I could remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;update its &lt;code&gt;class&lt;/code&gt; or &lt;code&gt;style&lt;/code&gt; directly&lt;/li&gt;
&lt;li&gt;update its parents' attributes, respectively&lt;/li&gt;
&lt;li&gt;insert or remove &lt;code&gt;style&lt;/code&gt; or &lt;code&gt;link&lt;/code&gt; elements anywhere in the document&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In order to watch any of those, we need &lt;code&gt;MutationObserver&lt;/code&gt; support - a DOM change observing interface supported in modern browsers (IE11+). I suppose that's the same that allows you to watch subtree or attribute modification in Elements pane of your favorite DevTools.&lt;/p&gt;

&lt;p&gt;So what does it provide us with? Simply the ability to listen to attribute changes (&lt;code&gt;class&lt;/code&gt; and &lt;code&gt;style&lt;/code&gt; fall in this category) as well as subtree modifications (external stylesheet insertion on removal lives here).&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Check for a Difference
&lt;/h2&gt;

&lt;p&gt;When we know &lt;em&gt;something has changed&lt;/em&gt;, we should check if there are any &lt;em&gt;actual&lt;/em&gt; changes since the changes we noticed might be totally unrelated. To do so, we will use &lt;code&gt;getComputedStyle&lt;/code&gt; - a useful method on &lt;code&gt;window&lt;/code&gt; supported by any modern browser starting IE9. What it does, is it returns a flat object of all CSS properties with values in a similar to CSS &lt;em&gt;computed&lt;/em&gt; tab in Chrome.&lt;/p&gt;

&lt;p&gt;Importantly, it returns a &lt;em&gt;live&lt;/em&gt; &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration"&gt;&lt;code&gt;CSSStyleDeclaration&lt;/code&gt; instance&lt;/a&gt;, which changes over time forcing us to keep a copy of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation sneak-peek
&lt;/h2&gt;

&lt;p&gt;The actual &lt;a href="https://github.com/oleggromov/sauron-style"&gt;source code&lt;/a&gt; lives in the repository, being rather compact by the way, but it might be interesting for you to see some details.&lt;/p&gt;

&lt;p&gt;First of all, I want to observe the watched element attributes changes. This is achieved easily:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mutationObserver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MutationObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkDiff&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mutationObserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;attributeFilter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;style&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;class&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this code does, is it creates a new instance of &lt;code&gt;MutationObserver&lt;/code&gt; class and sends it a callback, &lt;code&gt;this.checkDiff&lt;/code&gt;, as the only argument. Then it says: watch &lt;code&gt;this.node&lt;/code&gt; for the changes in &lt;code&gt;style&lt;/code&gt; and &lt;code&gt;class&lt;/code&gt; attributes only and invoke the callback on these changes.&lt;/p&gt;

&lt;p&gt;Later, in &lt;code&gt;this.checkDiff&lt;/code&gt; we want to see if the actual styles have changed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;checkDiff&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getStyle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getDiff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newStyle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscriber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscriber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newStyle&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above gets the current style and compares it against the stored copy. Then, if there's any difference, we store the new one for the future and invoke a subscriber function if it has been set already.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;this.getStyle&lt;/code&gt; returns a shallow copy of &lt;code&gt;this.computedStyle&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;getStyle&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;getCopy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;computedStyle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;this.computedStyle&lt;/code&gt; which is a reference to the mentioned above &lt;code&gt;CSSStyleDeclaration&lt;/code&gt; instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;computedStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getComputedStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Observing Other Elements
&lt;/h3&gt;

&lt;p&gt;It would be more or less it if we didn't care about other elements like parents' attribute changes or &lt;code&gt;style&lt;/code&gt;/&lt;code&gt;link[rel=stylesheet]&lt;/code&gt; insertion on removal. To do so, we need another entity, which I called &lt;code&gt;DocumentObserver&lt;/code&gt;, to watch document subtree modifications including attribute changes. It looks like this in the class &lt;code&gt;constructor&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MutationObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mutations&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;mutations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;attributeFilter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;class&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;childList&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;subtree&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's quite similar to the other &lt;code&gt;MutationObserver&lt;/code&gt; use case but here we treat every &lt;code&gt;mutation&lt;/code&gt; separately and watch changes on &lt;code&gt;window.document&lt;/code&gt;. Here we say roughly this: observe &lt;code&gt;class&lt;/code&gt; attribute modifications and children insertion/removal for &lt;code&gt;window.document&lt;/code&gt; and its children. Then call &lt;code&gt;this.observe&lt;/code&gt; for any relevant mutation.&lt;/p&gt;

&lt;p&gt;Observation code is very simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;observe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mutation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mutation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;childList&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkElements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mutation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mutation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;attributes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;invokeAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essentially, it checks the type of the mutation and proceeds to a corresponding branch. It's either call to &lt;code&gt;this.invokeAll&lt;/code&gt;, which just invokes all subscribers, or a few additional checks aimed to call &lt;code&gt;this.invokeAll&lt;/code&gt; only when a &lt;code&gt;link&lt;/code&gt; or a &lt;code&gt;style&lt;/code&gt; element is inserted.&lt;/p&gt;

&lt;p&gt;This part, the &lt;code&gt;DocumentObserver&lt;/code&gt;, is used from within &lt;code&gt;SauronStyle&lt;/code&gt; like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentObserver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getDocumentObserver&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listenerId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentObserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkDiff&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we use it as a singleton because we only have one document. Second, we subscribe the same &lt;code&gt;this.checkDiff&lt;/code&gt; to relevant changes to the document.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issues
&lt;/h2&gt;

&lt;p&gt;Well, this seems to work decently well but are there any problems?&lt;/p&gt;

&lt;p&gt;First of all, the performance is low. We often call &lt;code&gt;getComputedStyle&lt;/code&gt; and a call takes a few milliseconds, from 1 to 5-6 on my MacBook '2013. It's slow. Imagine a few thousand elements on a page which you want to observe. Will it take a few seconds to react to a DOM change? Yes, it will.&lt;/p&gt;

&lt;p&gt;Second, the algorithm is more of proof-of-concept quality rather than production-ready. We call &lt;code&gt;checkDiff&lt;/code&gt; method extensively, for any change in DOM that sometimes won't be related at all to the element we observe. I guess this additional computational complexity can be eliminated by computing and storing element styles outside DOM. But this could lead to more mistakes in difference detection and &lt;em&gt;much bigger&lt;/em&gt; comprehension complexity.&lt;/p&gt;

&lt;p&gt;I'm also not quite sure that I haven't forgotten any other ways to affect element styles.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Help
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;tell me if you have ever needed anything like that&lt;/li&gt;
&lt;li&gt;think and share your thoughts about any other possible ways of detecting style changes&lt;/li&gt;
&lt;li&gt;give &lt;a href="https://github.com/oleggromov/sauron-style"&gt;the library&lt;/a&gt; a star on GitHub&lt;/li&gt;
&lt;li&gt;actually use it in one of your projects! 👻&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for your attention!&lt;/p&gt;

&lt;p&gt;P.S. There's also a &lt;a href="http://oleggromov.com/notes/2018-02-observing-style-changes/"&gt;cross-posting of this article to my personal blog&lt;/a&gt;. Please take a look if you're interested in other development-related articles or just want to get in touch with me. &lt;/p&gt;

</description>
      <category>css</category>
      <category>changes</category>
      <category>javascript</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Declarativity Comes at a Price</title>
      <dc:creator>Oleg Gromov</dc:creator>
      <pubDate>Sun, 02 Jul 2017 21:35:16 +0000</pubDate>
      <link>https://dev.to/oleggromov/declarativity-comes-at-a-price</link>
      <guid>https://dev.to/oleggromov/declarativity-comes-at-a-price</guid>
      <description>&lt;p&gt;There is a widely held notion, and I agree, that declarative code is better than imperative. It is less error-prone, usually much more eloquent and neat and thus much more maintainable. It is a good principle to follow on a day-to-day basis when you use existing declarative libraries like the JavaScript standard library (&lt;code&gt;Array&lt;/code&gt;/&lt;code&gt;Object&lt;/code&gt; methods etc.), underscore/lodash or React. However, when it comes to making a decision to either write some declarative code (and therefore much more generalized) or just leave an imperative ad hoc solution, I suggest thinking at least twice.&lt;/p&gt;

&lt;p&gt;Every algorithm has specific complexity; not only does it have computational complexity (declared by means of time/memory it takes to run on different input sizes), but also a &lt;em&gt;complexity of writing and understanding the code&lt;/em&gt; that implements it. The latter primarily falls to programmers who work with the code, and in the world of budgets and deadlines is also a valid point of concern.&lt;/p&gt;

&lt;p&gt;What I state in this article’s title, &lt;em&gt;declarativity comes at a price&lt;/em&gt;, can be split in a few theses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation Cost Might Be Higher
&lt;/h2&gt;

&lt;p&gt;Whenever you decide to write something declaratively and have already implemented required primitives, like &lt;code&gt;map&lt;/code&gt; or &lt;code&gt;filter&lt;/code&gt; for arrays, you might be fine. Someone has already spent time writing and debugging it, and the only thing is left to do is understand how these primitives work and build your own algorithm of these small pieces. What is even better, once you understand how these building blocks work you acquire a rare skill of writing concise code with ease, which must be appreciated by virtually any good programmer in the world.&lt;/p&gt;

&lt;p&gt;On the other hand, when a problem you’re solving or a solution you’re picking is not so common and you cannot find needed “blocks”, you might be facing a tough decision of implementing them on your own. Sometimes generalization and abstraction require much more effort you will or can make.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comprehension and Debugging Price Might Be Higher
&lt;/h2&gt;

&lt;p&gt;Declarative code looks clearer at first glance but this impression is likely to change when it comes to deep comprehension and debugging. Simple things like &lt;code&gt;map&lt;/code&gt; or &lt;code&gt;filter&lt;/code&gt; are relatively well known and understood, more complex things like React’s component lifecycle are much more sophisticated, and self-implemented and likely not documented and/or tested primitives can be your worst nightmare. You might end up unraveling abstractions your coworker came up with a long time ago or even rewriting them in order to make it work as you expect.&lt;/p&gt;

&lt;p&gt;Generalized solutions of abstract problems, which declarative code comprises in essence, are hard. When you generalize an idea and explain it to your friend you might simplify it as well for sake of understanding; when you generalize algorithm, on the other hand, you likely create more and more edge cases because otherwise the code won’t work. It leads to more complications compared to an original smaller issue, more tests to be written and more time to be spent comprehending.&lt;/p&gt;

&lt;p&gt;And furthermore, we love eloquence and neatness in our code. A generalized solution might be not so good in the first place and you’ll spend hours to make it look better, whereas the original problem’s solution could have taken only a few minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Don’t get me wrong, I agitate neither against declarative code nor for it. Just be aware of the costs. When you’re lucky to have necessary tools, go ahead and use them. When you encounter a stinky imperative code in your shiny declarative React app, you most likely have a reason to be concerned. Just try to think twice and make a deliberate decision. We won’t get closer to good and working code just echoing dogmas that are being said on every corner. Considering implementation and comprehension and debugging costs, on the other hand, might help to come up with the right decision, whether it is leaving the code as is or paying the price for making it declarative and more generalized.&lt;/p&gt;




&lt;p&gt;&lt;a href="http://oleggromov.com/notes/2017-07-declarativity-comes-at-a-price/?utm_source=devto"&gt;This article was originally posted in my blog oleggromov.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>dogma</category>
    </item>
  </channel>
</rss>
