<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.2">Jekyll</generator><link href="https://mohsen.dev/feed.xml" rel="self" type="application/atom+xml" /><link href="https://mohsen.dev/" rel="alternate" type="text/html" /><updated>2022-08-12T15:32:47+00:00</updated><id>https://mohsen.dev/feed.xml</id><title type="html">mohsen</title><subtitle>a personal blog where I write about software engineering, productivity, hunting down bugs and products I like</subtitle><entry><title type="html">APH: Avoidable Person-Hours</title><link href="https://mohsen.dev/2022/08/12/aph-avoidable-person-hours.html" rel="alternate" type="text/html" title="APH: Avoidable Person-Hours" /><published>2022-08-12T00:00:00+00:00</published><updated>2022-08-12T00:00:00+00:00</updated><id>https://mohsen.dev/2022/08/12/aph-avoidable-person-hours</id><content type="html" xml:base="https://mohsen.dev/2022/08/12/aph-avoidable-person-hours.html">&lt;p&gt;A couple of years ago, I made up a new unit to measure the efficiency and necessity of meetings: APH (Avoided Person-Hours)
&lt;!--more--&gt;
Let me explain it. “Avoidable Work” is work that is not necessary, wrong, and wasted and it should be avoided.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Sometimes parties and stakeholders are not on the same page.&lt;/li&gt;
  &lt;li&gt;Sometimes customers’ request is misunderstood.&lt;/li&gt;
  &lt;li&gt;Sometimes other forms of communication are slow and inefficent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And many more issues that all lead to wasted hours of avoidable work.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How many unnecessary person-hours does holding a meeting can help you to avoid in the future?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I remember once a customer asked us to add a feature. It sounded like a reasonable request and would take 2-3 months of work.
But they hadn’t told us why they needed that feature.
We met with them to understand the bigger picture and design the system to accommodate the probable future requests.
We realized that what they wanted to do was already possible with the existing features. So with a 1-hour meeting, we avoided 2-3 months of work.
That was a valuable meeting and a precious lesson.&lt;/p&gt;

&lt;p&gt;For each meeting, ask yourself:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;How many unnessary person-hours can you avoid by that meeting?&lt;/li&gt;
  &lt;li&gt;Could that avoidable work have been avoided in other ways? Chat? Email? Shared doc?&lt;/li&gt;
  &lt;li&gt;Could you avoid even more unnecessary person-hours?&lt;/li&gt;
  &lt;li&gt;How can you avoid similar type of avoidable work in the future without having to have another meeting like this?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Measuring meetings’ APH not only allows you to decide if a meeting is required or not,
it also helps you to choose the form, participants, and agenda to maximize yout meeting’s APH.&lt;/p&gt;</content><author><name></name></author><category term="Meting" /><summary type="html">A couple of years ago, I made up a new unit to measure the efficiency and necessity of meetings: APH (Avoided Person-Hours)</summary></entry><entry><title type="html">make up your knapsack</title><link href="https://mohsen.dev/2022/08/05/make-up-your-knapsack.html" rel="alternate" type="text/html" title="make up your knapsack" /><published>2022-08-05T00:00:00+00:00</published><updated>2022-08-05T00:00:00+00:00</updated><id>https://mohsen.dev/2022/08/05/make-up-your-knapsack</id><content type="html" xml:base="https://mohsen.dev/2022/08/05/make-up-your-knapsack.html">&lt;p&gt;What I know about myself is that my decision-making capacity at any given moment is limited. I’ve started seeing my capacity as a knapsack.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;Then I put anything I need to decide in one of the three imaginary buckets: Small, Medium, and Large. The definition of each size is very subjective. For me, for example:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Small: Tea or coffee? Which cloth to wear today?&lt;/li&gt;
  &lt;li&gt;Medium:  Which cloth to buy? Which restaurant to go to?&lt;/li&gt;
  &lt;li&gt;Large: Accepting a job offer, buying a house or a car&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Over the first few months, I observed how I dealt with decisions and got a grasp of my decision-making knapsack capacity. Although my knapsack capacity changes under different circumstances (pressure, stress, …) but not significantly. I know, for example, at any given moment, I can deal with:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;2 small + 1 medium&lt;/li&gt;
  &lt;li&gt;Or two medium&lt;/li&gt;
  &lt;li&gt;Or one large&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But not more. If the knapsack is full, I take out  (decide or put off) some stuff first and only then I put in the new stuff, as long as it does not exceed the knapsack’s capacity.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://hbr.org/2012/09/simple-rules-for-a-complex-world&quot;&gt;Keep it simple&lt;/a&gt; though to avoid ending up with a hard &lt;a href=&quot;https://en.wikipedia.org/wiki/Knapsack_problem&quot;&gt;Knapsack Problem&lt;/a&gt; :)&lt;/p&gt;</content><author><name></name></author><category term="decision-making" /><summary type="html">What I know about myself is that my decision-making capacity at any given moment is limited. I’ve started seeing my capacity as a knapsack.</summary></entry><entry><title type="html">SwiftUI: Double-Edged Sword</title><link href="https://mohsen.dev/2020/06/21/swiftui-double-edged-sword.html" rel="alternate" type="text/html" title="SwiftUI: Double-Edged Sword" /><published>2020-06-21T00:00:00+00:00</published><updated>2020-06-21T00:00:00+00:00</updated><id>https://mohsen.dev/2020/06/21/swiftui-double-edged-sword</id><content type="html" xml:base="https://mohsen.dev/2020/06/21/swiftui-double-edged-sword.html">&lt;p&gt;One reason that I favor SwiftUI over UIKit is that SwiftUI is architecture-less.
&lt;!--more--&gt;
That is, SwiftUI doesn’t assume what architecture you are going to use. In contrast to UIKit that assumes you build your app using the MVC pattern. Whatever architecture you come up with, eventually, MVC pattern creeps in somewhere somehow. Regardless of how consistent and flawless your architecture is, you are doomed to interact with UIKit, and these surfaces of interaction are where MVC pattern leaks into your code.
On the other hand, in SwiftUI you are completely free to choose the architecture you are comfortable with and don’t need to be worried about the Apple preference. This freedom allows you to build a more coherent and uniform architecture. Although, in lack of a scaffold, as we used to have in UIKit, this time instead of ending up with Massive View Controller, we may slide into the &lt;a href=&quot;https://en.wikipedia.org/wiki/Big_ball_of_mud&quot;&gt;Big ball of mud&lt;/a&gt;. More freedom comes at the cost of more responsibility.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/coybit/coybit.github.io/raw/master/assets/uikit/uikit.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;</content><author><name></name></author><category term="swiftui" /><category term="uikit" /><category term="architecture" /><summary type="html">One reason that I favor SwiftUI over UIKit is that SwiftUI is architecture-less.</summary></entry><entry><title type="html">salary: confidential</title><link href="https://mohsen.dev/2020/04/26/salary-confidential.html" rel="alternate" type="text/html" title="salary: confidential" /><published>2020-04-26T00:00:00+00:00</published><updated>2020-04-26T00:00:00+00:00</updated><id>https://mohsen.dev/2020/04/26/salary-confidential</id><content type="html" xml:base="https://mohsen.dev/2020/04/26/salary-confidential.html">&lt;p&gt;Recently, I disclosed my salary to someone and I couldn’t help myself asking if it was the right decision.
&lt;!--more--&gt;
Most people, including me, are usually unwilling to disclose their salary. Who does benefit from this secrecy? employer. It’s scary how the fear of being judged gets us to act against our self-interest. We fall into this trap because we translate our salary to our value and omit to separate our identifiy from our profession.&lt;/p&gt;

&lt;p&gt;I can think of 4 reasons for which people don’t want to talk about their salary:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;You disclose your salary and you find out that your mate, equally or less qualified, making more. You feel you have failed in selling yourself and your employee has exploited this opportunity and pay you less than you deserve. &lt;strong&gt;You feel you are a fool&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;You disclose your salary and &lt;strong&gt;people judge your ability and skills based on your salary&lt;/strong&gt;, not the other way around.&lt;/li&gt;
  &lt;li&gt;You are humble and are afraid that you may &lt;strong&gt;hurt your mate’s feelings&lt;/strong&gt; when they find out you’re making more money.&lt;/li&gt;
  &lt;li&gt;You think you are making more money than you deserve and are afraid that &lt;strong&gt;you wouldn’t be able to defend it&lt;/strong&gt; if someone questions you.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Of course, none of these reasons justifies this decision. But it’s what it is.&lt;/p&gt;

&lt;p&gt;I still have a few open questions though:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;How can we rephrase this topic in game theory terminology&lt;/li&gt;
  &lt;li&gt;How does it align with one my principle that says &lt;em&gt;“if you HAVE TO hide something, there is something WRONG.”&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;What is the share of the lack of a fair evaluation system in getting us to this paper on the crack solution (not to talk about salary to avoid conflict)?&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><category term="salary" /><category term="job" /><summary type="html">Recently, I disclosed my salary to someone and I couldn’t help myself asking if it was the right decision.</summary></entry><entry><title type="html">awkward phase</title><link href="https://mohsen.dev/2020/01/19/awkward_phase.html" rel="alternate" type="text/html" title="awkward phase" /><published>2020-01-19T00:00:00+00:00</published><updated>2020-01-19T00:00:00+00:00</updated><id>https://mohsen.dev/2020/01/19/awkward_phase</id><content type="html" xml:base="https://mohsen.dev/2020/01/19/awkward_phase.html">&lt;ul&gt;
  &lt;li&gt;Are you switching from your old architecture to a new elegant sophisticated promising one?&lt;/li&gt;
  &lt;li&gt;Are you moving from an inconsistent non-scalable UI to a design system based UI?&lt;/li&gt;
  &lt;li&gt;Are you swapping an old deprecated module with a brand new fresh one?&lt;/li&gt;
  &lt;li&gt;Are you migrating from an old fashion document-less backend to a new shining cutting-edge one?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So you’re in an awkward phase. Aren’t you?
&lt;!--more--&gt;
&lt;img src=&quot;https://raw.githubusercontent.com/coybit/coybit.github.io/master/assets/cognitive_load_chart.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;“Awkward phase” is the name I use to refer to &lt;em&gt;the transition phase from a state to a better one&lt;/em&gt;. It’s awkward because you’re not in a stable state. You’re neither in the source state nor in the destination state. You neither benefit from being in the state you’re familiar with nor benefit from the advantages that the better state provides. You still suffer from the flaws of the first state while you need to concentrate on how you can get to the better state without messing up. Your cognitive load (&lt;a href=&quot;https://en.wikipedia.org/wiki/Cognitive_load&quot;&gt;Cognitive load - Wikipedia&lt;/a&gt;) is two times more than before.&lt;/p&gt;

&lt;p&gt;We all were there at least a couple of times. We get excited for the bright stress-free future that the new state (new architecture, UI, module, backend) promises and are thrilled that we will be able to get rid of the old frustrating dead-end hard-to-maintain state (old architecture, UI, module, backend).&lt;/p&gt;

&lt;p&gt;But the path gets us there is dark and dangerous. We should not stop. We’ve got to run. We can not pause, deprioritize or abandon it once we start it. We can not just stand somewhere between. We should remember the transition phase is awkward. We have to maintain two documentation, two pieces of code, two sources of bugs, two solutions, two explanations, two sets of edge cases, … cognitive load x 2.&lt;/p&gt;

&lt;p&gt;Before entering into an awkward phase, make a plan, know exactly how you want to go to the new state, what risks you may face, what you need to have and what you need to do, then take your breath and run. In case you change your mind, don’t stop, don’t pause, don’t slow down. Come back to the previous state. Clean your footprint. Roll back to the old state. Don’t make people confused about what state you’re in. &lt;em&gt;Being in a bad state sometime is better than being in the awkward phase. Although minimizing cognitive load is always better.&lt;/em&gt;&lt;/p&gt;</content><author><name></name></author><category term="software" /><category term="engineering" /><category term="architecture" /><category term="refactor" /><category term="design" /><summary type="html">Are you switching from your old architecture to a new elegant sophisticated promising one? Are you moving from an inconsistent non-scalable UI to a design system based UI? Are you swapping an old deprecated module with a brand new fresh one? Are you migrating from an old fashion document-less backend to a new shining cutting-edge one? So you’re in an awkward phase. Aren’t you?</summary></entry><entry><title type="html">apple doesn’t slow iPhone down, we do</title><link href="https://mohsen.dev/2019/08/23/apple_does_not_slow_iphone_down_we_do.html" rel="alternate" type="text/html" title="apple doesn’t slow iPhone down, we do" /><published>2019-08-23T00:00:00+00:00</published><updated>2019-08-23T00:00:00+00:00</updated><id>https://mohsen.dev/2019/08/23/apple_does_not_slow_iphone_down_we_do</id><content type="html" xml:base="https://mohsen.dev/2019/08/23/apple_does_not_slow_iphone_down_we_do.html">&lt;p&gt;There has always been a conspiracy that Apple deliberatly slows iPhone devies down to make people to buy new one. Is it true?
&lt;!--more--&gt;&lt;/p&gt;

&lt;h3 id=&quot;part-i-i-lost-my-brand-new-iphone-️&quot;&gt;Part I: I lost my brand new iPhone ☹️&lt;/h3&gt;
&lt;p&gt;I lost my iPhone XS three weeks ago. I don’t want to buy a new one again any time soon. So I fished my old iPhone 5s out of my drawer. Setting it up, I noticed it is slow. To be accurate, it was too slow. Slower than when I was using it as my main device/phone. It’s unbearable. Why is it so? What happened in the last 2-3 months? &lt;a href=&quot;https://webcache.googleusercontent.com/search?q=cache:CNH3hYYmNXEJ:https://www.huffpost.com/entry/apple-new-iphones_n_5967626&quot;&gt;Has Apple done some magic to persuade me to buy a new phone&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;The answer is … No.&lt;/p&gt;

&lt;p&gt;Apple hasn’t done anything to deliberately throttle my phone.&lt;/p&gt;

&lt;h3 id=&quot;part-ii-a-craving-to-consume-more&quot;&gt;Part II: a craving to consume more&lt;/h3&gt;
&lt;p&gt;Probably you have blamed Chrome or Slack for using too much RAM too. But this is a wide and deep problem. It’s not easy to find a piece of software that is built with as much thought and effort put into making it memory efficent as developer used to do. Look at this supposedly tiny winy software that the only thig does is mirroring my screen on a conference room display. After keeping it open for 2 or 3 hours, it gets to the points:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/coybit/coybit.github.io/master/assets/apple_does_not_slow_iphone_down_we_do/activity.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Right now, I don’t have any important software open on my laptop and 11GB of RAM is already full. 6 years ago, my laptop had 2GB of RAM and it was enough!&lt;/p&gt;

&lt;p&gt;What’s going on under the hood? Why do softwares eat too much nowadays?&lt;/p&gt;

&lt;h3 id=&quot;part-iii-a-frame-drops-an-instrument-rises&quot;&gt;Part III: a frame drops, an instrument rises&lt;/h3&gt;
&lt;p&gt;When was the last time you monitor the performance of the app you’ve been developing? Is it part of your everyday routine? 
Most of the time we use them when something is terribly wrong: app crashes, UI freezes, scrolling looks erratic, customer complains. Rarely benchmarking is integrated into our development process. It’s more like an occasional thing.&lt;/p&gt;

&lt;p&gt;Barely you leave an interview haven’t answered some questions about big O notation. We can compare common data structures top off our mind. We know popular algorithms by heart. We can explain which ones outperform which ones. We all admit writing efficient software is precious. Yet everything in the market encourages use to leave old devices behind. The hardware industry goes forward fast and we’re trying to catch up. But it comes at a price: Old devices get ignored, their owners get forgotten.
But soon or later, we realize that the number of ignored users are growing and maybe we should include them again. So this is why Lite version of apps is becoming a thing (Facebook Lite, Spotify Lite, Twitter Lite, Skype Lite, … and just recently &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.google.android.apps.searchlite&amp;amp;hl=en&quot;&gt;Google Go Lite&lt;/a&gt;). Although many of them are nothing more than the existing product minus some features.&lt;/p&gt;

&lt;h3 id=&quot;part-iv-good-old-days&quot;&gt;Part IV: Good Old Days&lt;/h3&gt;
&lt;p&gt;Last year I read &lt;a href=&quot;http://fabiensanglard.net/gebbwolf3d/&quot;&gt;Game engine black book: Wolfenstein 3D&lt;/a&gt;. It’s fascinating. To me, it is a treasure chest. As &lt;a href=&quot;https://www.folklore.org/&quot;&gt;folklore&lt;/a&gt; and &lt;a href=&quot;https://www.youtube.com/playlist?list=PLi29TNPrdbwJLiB-VcWSSg-3iNTGJnn_L&quot;&gt;Code Secret&lt;/a&gt; are. Sometimes what you find on &lt;a href=&quot;https://www.reddit.com/r/gaming/comments/8ij644/the_bushes_and_clouds_in_super_mario_bros_are_the/&quot;&gt;reddit&lt;/a&gt; or in &lt;a href=&quot;https://www.theverge.com/2012/4/27/2980806/prince-of-persia-jordan-mechner-narrative-games&quot;&gt;an interview&lt;/a&gt; impresses you. They sound like fairy tales. When software development is more about crafting than wrestling with a bunch of technologies, tools, frameworks and sitting top of shaky stacks of unknown or hard-to-be-known layers. When people pay attention to each line of code they write and every byte of memory they use.&lt;/p&gt;

&lt;p&gt;I felt over the course of time we, developers, are getting negligent and careless. We believe memory is a customer’s problem, not ours.&lt;/p&gt;

&lt;h3 id=&quot;part-v-i-wont-suck-it-up-at-least-for-now&quot;&gt;Part V: I won’t suck it up (at least for now)&lt;/h3&gt;
&lt;p&gt;I’ve decided to develop my next iOS side project for an old iPhone. I even tried to find iPhone 4, but no success yet. 
I’m curious to see what obstacles I will encounter and how I can find my way around them.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/coybit/coybit.github.io/master/assets/apple_does_not_slow_iphone_down_we_do/challenge.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;</content><author><name></name></author><category term="iOS" /><category term="Apple" /><category term="performance" /><summary type="html">There has always been a conspiracy that Apple deliberatly slows iPhone devies down to make people to buy new one. Is it true?</summary></entry><entry><title type="html">daily standup: where scrum flys or dies</title><link href="https://mohsen.dev/2019/06/23/daily-standup-where-scrum-flys-or-dies.html" rel="alternate" type="text/html" title="daily standup: where scrum flys or dies" /><published>2019-06-23T00:00:00+00:00</published><updated>2019-06-23T00:00:00+00:00</updated><id>https://mohsen.dev/2019/06/23/daily-standup-where-scrum-flys-or-dies</id><content type="html" xml:base="https://mohsen.dev/2019/06/23/daily-standup-where-scrum-flys-or-dies.html">&lt;p&gt;It was roughly nine years ago when I attended my first official Scrum Daily Standup. I among my four teammates went to our manager office at 10 in the morning. After 10min, when we were done, I felt it was useless. Since then (almost) in every company I worked at, we had some kind of daily standup. Except for a few times, I never enjoyed being in a standup. 
&lt;!--more--&gt;
Usually, standup is the first thing a company/team starts with when they decide to adapt to Scrum or any variation of Agile methodology. Honestly, from company perspective, it is the cheapest and less risky part of Scrum. Just 5 minute per day.
Any implementation of Scrum Daily Standup I’ve experienced so far was kind of a failure, most of the time partially and sometimes completely. 
I, as an observer of all these failures, asked myself every time, after every standup, what needs to be changed? Until 5 months ago, when I learned how a standup suppose to be.&lt;/p&gt;

&lt;h3 id=&quot;2-years-ago-when-i-read-that-book&quot;&gt;2 Years Ago: When I read that book&lt;/h3&gt;
&lt;p&gt;Until 2 years ago, everything I knew about Scrum and Agile methodology I had learned from non-original resources. 2 years ago, accidentally, I found this book in a small abandon library in my previous workplace:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/coybit/coybit.github.io/raw/master/assets/standup/book.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It explains Scrum, in the purest form. If you want to learn or re-learn Scrum, it’s a must-read. What is my most important takeaway from this book? Scrum is a mindset which you build and the rest (backlog, standup, planning, retrospective, … ) comes after that. They are all inevitable results of this mindset. If you build this mindset, organically, gradually, over course of time, in search of solutions for natural problems your team struggles with, through process of customization, you invite them again and one day you realize you have been doing standup, backlog/sprint planning and retrospective, may under different names. You don’t know since when. But you invented them again and customized them according to your needs and have been using them to become and stay agile. I believe this the biggest mistake people make when they try to adapt to Scrum. They start from tools to get to mindset. But it’s the other way around:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/coybit/coybit.github.io/raw/master/assets/standup/result.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;5-months-ago-such-a-pleasure&quot;&gt;5 months ago: Such a pleasure&lt;/h3&gt;
&lt;p&gt;It’s was my first standup in the new company. I liked it. I enjoyed. After that, I felt we are more than a tech/dev team. I felt we are a squad, like how that book describes a scrum team. Every single standup was useful. It helped me to become agile, more flexible, more team-player. But why? What was the difference between the standups we held here with all other standups I’ve been in in the past?&lt;/p&gt;

&lt;h3 id=&quot;good-standup-bad-standup&quot;&gt;Good Standup, Bad Standup&lt;/h3&gt;
&lt;p&gt;OK. I don’t have a formula or theory (yet!). The only thing I have is a bunch of signs and flags which I have built my litmus test based on.&lt;/p&gt;

&lt;p&gt;A bad standup is like a reporting meeting, where you report to your direct manager or your customer. You talk more about the past and what you have done and less about the future and what you’re going to do. You attend the standup because your manager has asked you. You do it because your customer/manager wants to know more, every day, about the progress. You get bored. If you hadn’t attended it, you wouldn’t have missed anything important.&lt;/p&gt;

&lt;p&gt;A good standup is like being in a war room. It all about re-evaluating the situation, re-organizing the team accordingly, and proceed. The ultimate goal is filling each other’s gaps and build a complete team out of incomplete individuals.  During a good standup, you hear this kind of sentences a lot:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;I can pair up with you.&lt;/li&gt;
  &lt;li&gt;I can pick up this task.&lt;/li&gt;
  &lt;li&gt;Can you help me? I know you encountered a similar issue in the past.&lt;/li&gt;
  &lt;li&gt;I know how we can solve it. We can talk about it after the standup.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a good standup, people talk more about what they are going to do and less about what they have done. You attend it for yourself, for your team, because you’ve experienced how it increases your agility. Even when your manager/customer doesn’t attend standup, you still find it useful and necessary.&lt;/p&gt;

&lt;p&gt;Let’s model a standup with a graph. Each node in this graph is a person and we draw a line from A to B if at some point in standup A talks directly to B. This is how a bad standup looks like:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/coybit/coybit.github.io/raw/master/assets/standup/bad.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And this is how a good one is:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/coybit/coybit.github.io/raw/master/assets/standup/good.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;fly-or-die&quot;&gt;Fly or Die&lt;/h3&gt;
&lt;p&gt;Standup is important. If it fails, the whole implementation of Scrum will fail. You can look at it as an indicator. Every day you repeat it. Every day you have the chance to see if your standup is quality or not. If your team has adapted to the agile mindset or not. If you are on the right track or not. This 5min meeting reflects the sprint of your team and how far you are from being an agile, flexible, coherent team.&lt;/p&gt;</content><author><name></name></author><category term="scrum" /><category term="agile" /><category term="team" /><summary type="html">It was roughly nine years ago when I attended my first official Scrum Daily Standup. I among my four teammates went to our manager office at 10 in the morning. After 10min, when we were done, I felt it was useless. Since then (almost) in every company I worked at, we had some kind of daily standup. Except for a few times, I never enjoyed being in a standup.</summary></entry><entry><title type="html">a dead simple solution to lift up errors in ios</title><link href="https://mohsen.dev/2019/06/09/a-dead-simple-solution-to-lift-up-errors-in-iOS.html" rel="alternate" type="text/html" title="a dead simple solution to lift up errors in ios" /><published>2019-06-09T00:00:00+00:00</published><updated>2019-06-09T00:00:00+00:00</updated><id>https://mohsen.dev/2019/06/09/a-dead-simple-solution-to-lift-up-errors-in-iOS</id><content type="html" xml:base="https://mohsen.dev/2019/06/09/a-dead-simple-solution-to-lift-up-errors-in-iOS.html">&lt;p&gt;In this post, I want to show you how you can utilize &lt;a href=&quot;https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/using_responders_and_the_responder_chain_to_handle_events?language=objc&quot;&gt;the responder chain&lt;/a&gt; to bubble up an error message through your app UI structure till it gets to the node which can handle it. It is especially useful if you are a fan of &lt;a href=&quot;https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html&quot;&gt;Container View Controller&lt;/a&gt;.
&lt;!--more--&gt;
Responder Chain is a linked list built and maintained by iOS that represents the prioritized list of object that potentially can respond to events that occur in UI. If you like to learn more about Responder Chain pattern in general &lt;a href=&quot;https://refactoring.guru/design-patterns/chain-of-responsibility&quot;&gt;here&lt;/a&gt; or more specific in iOS &lt;a href=&quot;https://useyourloaf.com/blog/using-the-responder-chain/&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;https://swiftrocks.com/understanding-the-ios-responder-chain.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Suppose that you have a nested structure of views and view controllers that presents the UI of your app. If something goes wrong in any of this view controllers or views and you don’t want to handle the error there and you prefer you pass it up to its ancestors, you might use delegate pattern or closure or other solution. But you usually end up adding some kind of one-direction wire between views and view controllers which have parent-child relation. Fortunately, we already have this one-direction wire between parent and child for free and we just need to use it.&lt;/p&gt;

&lt;p&gt;Here is what you can do:&lt;/p&gt;
&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIResponder&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;@objc&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here we add a method to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UIResponder&lt;/code&gt; that consequently, this method will be available on any UIView, UIViewController, UIWindow or UIApplication. What it does is really simple, it passes the error to the ancestor of the current UIResponder object. If we override this method in a subclass of UIResponder, we will be able to catch the error and handle it however we like.&lt;/p&gt;

&lt;p&gt;You might use a more sophisticated parameter for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;showError&lt;/code&gt;. For example, you can pass an &lt;a href=&quot;https://developer.apple.com/documentation/swift/error&quot;&gt;Error&lt;/a&gt; instance, so that an UIResponder can handle just some type of error and passes those that don’t handle to its ancestor.&lt;/p&gt;

&lt;p&gt;Here is an example:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;WhiteViewController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIViewController&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;errorLabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UILabel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;viewDidLoad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;viewDidLoad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        
        &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backgroundColor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;white&lt;/span&gt;
        
        &lt;span class=&quot;c1&quot;&gt;// Add a child view controller&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;childVC&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;RedViewController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;childVC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frame&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bounds&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;insetBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;addChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;childVC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;addSubview&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;childVC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;childVC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;didMove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;toParent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;c1&quot;&gt;// Add a label for showing error messages&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;errorLabel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UILabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;addSubview&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errorLabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Show the error message and clear it after 1sec&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;errorLabel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;DispatchQueue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;asyncAfter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;deadline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;weak&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errorLabel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;RedViewController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIViewController&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;errorLabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UILabel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;viewDidLoad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;viewDidLoad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        
        &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backgroundColor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;red&lt;/span&gt;
        
        &lt;span class=&quot;c1&quot;&gt;// Add a child view controller&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;childVC&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;GreenTableViewController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;childVC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frame&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bounds&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;insetBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;addChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;childVC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;addSubview&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;childVC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;childVC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;didMove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;toParent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;c1&quot;&gt;// Add a label for showing error messages&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;errorLabel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UILabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;addSubview&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errorLabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fatal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Show the error message and clear it after 1Sec&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;errorLabel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;DispatchQueue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;asyncAfter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;deadline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;weak&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errorLabel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Pass the error to the ancestor&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;SimpleCellView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UITableViewCell&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setSelected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;selected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;animated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setSelected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;selected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;animated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;animated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;selected&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Something went wrong!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;GreenTableViewController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UITableViewController&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;viewDidLoad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;viewDidLoad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        
        &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backgroundColor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;green&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tableView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;SimpleCellView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;forCellReuseIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;SimpleCellView&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;numberOfSections&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;tableView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UITableView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;tableView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;tableView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UITableView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numberOfRowsInSection&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;section&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;tableView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;tableView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UITableView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cellForRowAt&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;indexPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;IndexPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UITableViewCell&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;cell&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tableView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;dequeueReusableCell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;withIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;SimpleCellView&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as?&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;SimpleCellView&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;textLabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Cell #&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;indexPath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fatal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;indexPath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIResponder&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;@objc&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is the responder chain of this example:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Responder Chain:
 
UIApplication (next: nil)
 |
 |__ UIWindow (next: UIApplication)
      |
      |__ WhiteViewController (next: UIWindow)
            |
            |__ RedViewController (next: WhiteViewController)
                 |
                 |__ GreenTableViewController (next: RedViewController)
                      |
                      |__ SimpleCellView #1  (next: GreenTableViewController)
                          SimpleCellView #2  (next: GreenTableViewController)
                          SimpleCellView #3  (next: GreenTableViewController)
                          SimpleCellView #4  (next: GreenTableViewController)
                          SimpleCellView #5  (next: GreenTableViewController)
                          SimpleCellView #6  (next: GreenTableViewController)
                          SimpleCellView #7  (next: GreenTableViewController)
                          SimpleCellView #8  (next: GreenTableViewController)
                          SimpleCellView #9  (next: GreenTableViewController)
                          SimpleCellView #10 (next: GreenTableViewController)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/coybit/coybit.github.io/raw/master/assets/responder-chain-ui.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SimpleCellView&lt;/code&gt; when user selects a cell, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;showError&lt;/code&gt; is called:&lt;/p&gt;
&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setSelected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;selected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;animated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setSelected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;selected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;animated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;animated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;selected&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Something went wrong!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Because we haven’t overriden &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;showError&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SimpleCellView&lt;/code&gt;, the default implementation is called:&lt;/p&gt;
&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The next item in the chain is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GreenTableViewController&lt;/code&gt; which doesn’t have an overridden version of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;showError&lt;/code&gt;, so the default implementation is called again and the next item in the responder chain is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RedViewController&lt;/code&gt;. It has an implementation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;showError&lt;/code&gt; but catches and handles the error which is fatal, otherwise passes it to its ancestor which in this case is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WhiteViewController&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fatal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Show the error message and clear it after 1Sec&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;errorLabel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;DispatchQueue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;asyncAfter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;deadline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;weak&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errorLabel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Pass the error to the ancestor&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Those errors which are not fatal get to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WhiteViewController&lt;/code&gt; and it handles them all equally:&lt;/p&gt;
&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Show the error message and clear it after 1sec&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;errorLabel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;DispatchQueue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;asyncAfter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;deadline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;weak&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errorLabel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name></name></author><category term="UIKit" /><category term="Swift" /><category term="iOS" /><summary type="html">In this post, I want to show you how you can utilize the responder chain to bubble up an error message through your app UI structure till it gets to the node which can handle it. It is especially useful if you are a fan of Container View Controller.</summary></entry><entry><title type="html">__NSSingleObjectArrayI: an existential crisis</title><link href="https://mohsen.dev/2019/06/02/__NSSingleObjectArrayI-an-existential-crisis.html" rel="alternate" type="text/html" title="__NSSingleObjectArrayI: an existential crisis" /><published>2019-06-02T00:00:00+00:00</published><updated>2019-06-02T00:00:00+00:00</updated><id>https://mohsen.dev/2019/06/02/__NSSingleObjectArrayI-an-existential-crisis</id><content type="html" xml:base="https://mohsen.dev/2019/06/02/__NSSingleObjectArrayI-an-existential-crisis.html">&lt;p&gt;When you create an new instance of &lt;a href=&quot;https://developer.apple.com/documentation/foundation/nsarray/1460096-arraywithobjects?language=objc&quot;&gt;NSArray&lt;/a&gt;, inside &lt;a href=&quot;https://developer.apple.com/documentation/foundation/nsarray/1460096-arraywithobjects?language=objc&quot;&gt;arrayWithObjects:count:&lt;/a&gt;  (which can be called directly and is called indirectly by other constructors and also is that method is used internally to create an array from a literal array) depending on how many items it has, under the hood &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSArray&lt;/code&gt; may create either an instance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__NSArrayI&lt;/code&gt;(&lt;a href=&quot;https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/CoreFoundation.framework/__NSSingleObjectArrayI.h&quot;&gt;Runtime Header file&lt;/a&gt;) or an instance of  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__NSSingleObjectArrayI&lt;/code&gt; (&lt;a href=&quot;https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/CoreFoundation.framework/__NSSingleObjectArrayI.h&quot;&gt;Runtime Header file&lt;/a&gt;). Actually, if the array contains one item, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSArray&lt;/code&gt; create an instance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__NSSingleObjectArrayI&lt;/code&gt;, otherwise &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__NSArrayI&lt;/code&gt; gets used.
&lt;!--more--&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-objective-c&quot;&gt;NSArray *arr1 = @[@(1)]; // arr1 is __NSSingleObjectArrayI
NSArray *arr2 = @[@(1), @(2)]; // arr2 is __NSArrayI
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;By looking at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__NSSingleObjectArrayI.h&lt;/code&gt; you will notice that this class has a protected variable, called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_object&lt;/code&gt;, that I guess it is where the single item of the array is stored.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-objective-c&quot;&gt;@interface __NSSingleObjectArrayI : NSArray {
    id  _object;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As soon as you learn that single object arrays are treated differently, an important question arises: &lt;strong&gt;What is the necessity of having a separate type for array that has just one object?&lt;/strong&gt;
My first guess was Performance, either in terms of speed or memory usage, or maybe both. I tested my hypothesizes and I like to share the results with you. If you like to learn more about benchmarking in Objective-C/Swift, read “&lt;a href=&quot;https://nshipster.com/benchmarking/&quot;&gt;Benchmarking&lt;/a&gt;” by Mattt. To test my hypothesizes I utilizeed what I had learned from this article.&lt;/p&gt;

&lt;h3 id=&quot;hypothesis1-it-is-faster&quot;&gt;Hypothesis1: It is faster&lt;/h3&gt;

&lt;p&gt;I measured how much it takes to create an instance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSArray&lt;/code&gt;. The varibale of this experiment was the number of items the array contains. Also, I was curious if specifing the type of array’s items make any difference. So I repeated experiments once again but this type specified the type of arrays’ items:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Case#&lt;/th&gt;
      &lt;th&gt;Array&lt;/th&gt;
      &lt;th&gt;Time&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Case1&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSArray *arr = @[@(1)];&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;2.62712e-05 s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Case2&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSArray&amp;lt;NSNumber *&amp;gt; *arr = @[@(1)];&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;2.59094e-06 s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Case3&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSArray *arr = @[@(1),@(2)];&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;1.91713e-06 s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Case4&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSArray&amp;lt;NSNumber *&amp;gt; *arr = @[@(1),@(2)];&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;2.41189e-06 s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Case5&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSArray *arr = @[@(1),@(2),@(3),@(4),@(5),@(6),@(7),@(8)];&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;2.89804e-06 s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Case6&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSArray&amp;lt;NSNumber *&amp;gt; *arr = @[@(1),@(2),@(3),@(4),@(5),@(6),@(7),@(8)];&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;3.00701e-06 s&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;In general, create an instance of  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__NSSingleObjectArrayI&lt;/code&gt; is slower than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__NSArrayI&lt;/code&gt;, and specifying the type of array’s items makes the creation faster. 
Then I measured the amount of time it takes to access the first item of an array. The varible was the type of array, but the access method was the same:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Case#&lt;/th&gt;
      &lt;th&gt;Array&lt;/th&gt;
      &lt;th&gt;Time&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Case1&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSArray *arr = @[@(1)];&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;4.65124 s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Case2&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSArray&amp;lt;NSNumber *&amp;gt; *arr = @[@(1)];&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;4.61453 s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Case3&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSArray *arr = @[@(1),@(2)];&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;4.11629 s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Case4&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSArray&amp;lt;NSNumber *&amp;gt; *arr = @[@(1),@(2)];&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;4.04419 s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Case5&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSArray *arr = @[@(1),@(2),@(3),@(4),@(5),@(6),@(7),@(8)];&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;4.05391 s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Case6&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSArray&amp;lt;NSNumber *&amp;gt; *arr = @[@(1),@(2),@(3),@(4),@(5),@(6),@(7),@(8)];&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;4.09293 s&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;As you can see, accessing the first item of an array of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__NSSingleObjectArrayI&lt;/code&gt; type is slower than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__NSArrayI&lt;/code&gt;, and specifying the type of array’s items enables us to access the first item faster.&lt;/p&gt;

&lt;h3 id=&quot;hypothesis2-it-reduces-memory-usage&quot;&gt;Hypothesis2: It reduces memory usage&lt;/h3&gt;

&lt;p&gt;I ran another experiment. This time in each test case, I created 1000 instance of array with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;N&lt;/code&gt; items and used Instruments to measure how much memory was used to store these instances. This time, the variable of the experiment was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;N&lt;/code&gt;: Here is the result:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Case#&lt;/th&gt;
      &lt;th&gt;Array&lt;/th&gt;
      &lt;th&gt;Memory&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Case1&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@[@(1)]&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;156,25 Kb&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Case2&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@[@(1),@(2)]&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;312,50 Kb&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Case3&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@[@(1),@(2),@(3)]&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;468,75 Kb&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Case4&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@[@(1),@(2),@(3),@(4)]&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;468,75 Kb&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Case5&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@[@(1),@(2),@(3),@(4),@(5)]&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;625,00 Kb&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Case6&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@[@(1),@(2),@(3),@(4),@(5),@(6)]&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;781,25 Kb&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Even when we compare memory usage, there is no significant difference between these two (size of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@[@(1),@(2)]&lt;/code&gt; x 2 = size of  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@[@(1)]&lt;/code&gt;, that makes sense).&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;I don’t still understand the reason behind having a separate type for immutable arrays that have just one item, though I know now that neither is faster nor used less memory. On the other hand, I couldn’t find a use case where someone needs to create thousands instance of single object array so might this subtle difference become important for the developer. Maybe this is why no one has ever complained about that.
The only case where I can image this difference might be important is where a JSON gets decoded. Because if a JSON array has just one item, the decoded type will be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__NSSingleObjectArrayI&lt;/code&gt;. So if you are working on a program that its performance is critical and somewhere in this program you have to decode a huge JSON which has many single item arrays, you should be more careful.&lt;/p&gt;</content><author><name></name></author><category term="Objective-C" /><category term="iOS" /><category term="Foundation" /><summary type="html">When you create an new instance of NSArray, inside arrayWithObjects:count: (which can be called directly and is called indirectly by other constructors and also is that method is used internally to create an array from a literal array) depending on how many items it has, under the hood NSArray may create either an instance of __NSArrayI(Runtime Header file) or an instance of __NSSingleObjectArrayI (Runtime Header file). Actually, if the array contains one item, NSArray create an instance of __NSSingleObjectArrayI, otherwise __NSArrayI gets used.</summary></entry><entry><title type="html">bash: going down the rabbit hole</title><link href="https://mohsen.dev/2019/05/26/bash-going-down-the-rabbit-hole.html" rel="alternate" type="text/html" title="bash: going down the rabbit hole" /><published>2019-05-26T00:00:00+00:00</published><updated>2019-05-26T00:00:00+00:00</updated><id>https://mohsen.dev/2019/05/26/bash-going-down-the-rabbit-hole</id><content type="html" xml:base="https://mohsen.dev/2019/05/26/bash-going-down-the-rabbit-hole.html">&lt;h3 id=&quot;question&quot;&gt;Question&lt;/h3&gt;
&lt;p&gt;Last week when I was looking at a bash script file, I saw this line:&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$FOLDER_NAME&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ios&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;lib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;lib-osx-amd64&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;lib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;lib-linux32&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;I’m not a bash expert, so this line caught my attention. At first, I thought what &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A &amp;amp;&amp;amp; B || C&lt;/code&gt; does is similar to what &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A ? B : C&lt;/code&gt; in many programming languages does. It takes a few hours of debugging, reading and thinking to realize this hypothesis was wrong!
&lt;!--more--&gt;
Actually, if you’re using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A &amp;amp;&amp;amp; B || C&lt;/code&gt; in bash how you use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A ? B : C&lt;/code&gt;  in other programming languages without knowing what is happening under the hood, and it works for you, you are just lucky!&lt;/p&gt;

&lt;h3 id=&quot;contradiction&quot;&gt;Contradiction&lt;/h3&gt;
&lt;p&gt;After seeing that line, I started searching on the web to learn what that line means. The first thing I noticed after reading some articles and answers was that many people don’t know that line gets evaluated by bash and they have given up to understand it. The vaguest aspect of evaluation was the precedence of operators that looks is different than when they are being used within a condition expression. Actually, you can not find any piece of information about it. The more you search, the less you find. The only thing you can find is the table of Operator Precedence  ( for instance &lt;a href=&quot;https://www.tldp.org/LDP/abs/html/opprecedence.html&quot;&gt;this one&lt;/a&gt; ) that doesn’t say anything about when these operators are used in this kind of usages.
But at least you know that if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;||&lt;/code&gt; getting used within a condition, how they get evaluated. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt; has a higher precedence than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;||&lt;/code&gt;. So:&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; A &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; B &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; C &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;First &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B &amp;amp;&amp;amp; C&lt;/code&gt; is evaluated ( lets call this expression &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;q&lt;/code&gt; ). Then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A || q&lt;/code&gt; is evaluated.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; A &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; B &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; C &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; D &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ol&gt;
  &lt;li&gt;First this expression &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;q := (A &amp;amp;&amp;amp; B)&lt;/code&gt; (  note: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;q := X&lt;/code&gt; means from now on, we refer to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X&lt;/code&gt; as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;q&lt;/code&gt; )&lt;/li&gt;
  &lt;li&gt;Then this one &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p := (C &amp;amp;&amp;amp; D)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;And finally, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;q || p&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But what about when these two operators are used outside of a conditional expression? Are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;||&lt;/code&gt; we are using in a conditional expression and the ones I saw in the bash file, in essence, the same thing. Are we tricking Bash and uses AND and OR logical operators to simulate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;?:&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;When you can not find your answer by searching on the web, it means you need to get your hand dirty! Let’s take a look into the bash source code.&lt;/p&gt;

&lt;h3 id=&quot;how-to-set-up-our-lab&quot;&gt;How to set up our lab&lt;/h3&gt;
&lt;p&gt;Obviously, there are thousands of thousands of way to set up your lab, but here I’m showing you how I did it for this example:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Download &lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;Visual Studio Code&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Download &lt;a href=&quot;https://code.visualstudio.com/docs/languages/cpp#_debugging&quot;&gt;C/C++ Extension&lt;/a&gt; for Visual Studio Code&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Clone &lt;a href=&quot;https://github.com/bminor/bash&quot;&gt;bash source code&lt;/a&gt; ( it’s a mirror of the source code )&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Build it.
It’s really simple.
a. go to the source code dir
b. run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./configure&lt;/code&gt;
c. run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make&lt;/code&gt;
and once it is done, you find a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bash&lt;/code&gt; executable file in the directory
If you’re interested in learning more about the process, look at &lt;a href=&quot;https://github.com/bminor/bash/blob/master/INSTALL&quot;&gt;this file&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Run it
Be Careful: if you run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bash&lt;/code&gt; in your bash, your installed bash is executed. But if instead run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./bash&lt;/code&gt;, the executable bash file in the current directory is executed. So run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./bash&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/coybit/coybit.github.io/raw/master/assets/bash/bash-start.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Welcome to your brand new bash!&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Attach the debugger
To attach a debugger to the running bash, you need to config &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;launch.json&lt;/code&gt; file of VSCode. It’s super easy. Just follow &lt;a href=&quot;https://github.com/Microsoft/vscode-cpptools/blob/master/launch.md&quot;&gt;this instruction&lt;/a&gt;:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;launch.json&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;Use&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;IntelliSense&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;learn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;about&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;possible&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;attributes.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;Hover&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;descriptions&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;existing&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;attributes.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;For&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;more&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;information&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;visit:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;https://go.microsoft.com/fwlink/?linkid=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;830387&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;0.2.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;configurations&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(lldb) Attach&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cppdbg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;request&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;attach&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;program&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;${workspaceFolder}/bash&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;processId&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;${command:pickProcess}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;MIMode&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;lldb&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;After that, the only thing you need to do is running the debuger.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/coybit/coybit.github.io/raw/master/assets/bash/bash-attaching-debugger.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once the debugger is attached to the running bash, you can add a breakpoint, watch variables, executing the code line by line,…&lt;/p&gt;

&lt;h3 id=&quot;connectional-and-vs-conditional-and&quot;&gt;Connectional AND vs Conditional AND&lt;/h3&gt;
&lt;p&gt;I made the running bash to run these two commands and by adding a breakpoint and checking variables while the commands were getting executed, I tried to understand how bash evaluates them.&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; A &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; B &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; A &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; B &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To save your time, I want to show you where you should add your breakpoint. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shell.c&lt;/code&gt; is the bash entry point ( it’s where you can find the bash main() function ). &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; function calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reader_loop&lt;/code&gt; function that is in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eval.c&lt;/code&gt;. This function waits till you enter a command in bash after parsing it and building a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;command&lt;/code&gt; object, sends it to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execute_command&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execute_command.c&lt;/code&gt; file and from there the command is sent to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execute_command_internal&lt;/code&gt; in the same file. In the scope of this function, there is a variable called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;command&lt;/code&gt; which is of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;command&lt;/code&gt; type ( the definition in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;command.h&lt;/code&gt; ) and it contains the parsed command entered into bash by a user. the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;command&lt;/code&gt; type is really interesting. It is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; with 4 general-purpose fields and one union, which represents details of command according to the command type.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* What a command looks like. */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;command_type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;cm&quot;&gt;/* FOR CASE WHILE IF CONNECTION or SIMPLE. */&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;            &lt;span class=&quot;cm&quot;&gt;/* Flags controlling execution environment. */&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;            &lt;span class=&quot;cm&quot;&gt;/* line number the command starts on */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;REDIRECT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;redirects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;        &lt;span class=&quot;cm&quot;&gt;/* Special redirects for FOR CASE, etc. */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;union&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;for_com&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;For&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;case_com&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Case&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;while_com&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;While&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;if_com&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;If&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;simple_com&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Simple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;function_def&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Function_def&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;group_com&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;cp&quot;&gt;#if defined (SELECT_COMMAND)
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;select_com&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;        &lt;span class=&quot;cp&quot;&gt;#if defined (DPAREN_ARITHMETIC)
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arith_com&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Arith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;        &lt;span class=&quot;cp&quot;&gt;#if defined (COND_COMMAND)
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cond_com&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Cond&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;        &lt;span class=&quot;cp&quot;&gt;#if defined (ARITH_FOR_COMMAND)
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arith_for_com&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ArithFor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;subshell_com&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Subshell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;coproc_com&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Coproc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;COMMAND&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For example, when you run this command:&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; A &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; B &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;1 &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;2 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;the parser builds a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;command&lt;/code&gt; object like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/coybit/coybit.github.io/raw/master/assets/bash/bash-command.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Back to the question with which we started this section when the entered command is:&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; A &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; B &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The bash parser generates this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;command&lt;/code&gt; and passes it down to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execute_command&lt;/code&gt;.:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/coybit/coybit.github.io/raw/master/assets/bash/bash-cm_cond.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cm_cond&lt;/code&gt; means this command is a of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cond_com&lt;/code&gt; type. By looking at the definitaion of this structure:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cond_com&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;WORD_DESC&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;op&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cond_com&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;COND_COM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;we learn that:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;left&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;right&lt;/code&gt; are of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cond_com&lt;/code&gt; type.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;type&lt;/code&gt; can be any of this values:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#define COND_AND    1
#define COND_OR        2
#define COND_UNARY    3
#define COND_BINARY    4
#define COND_TERM    5
#define COND_EXPR    6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So it is a tree. I’ve drawn this tree to make it easier what the parser has generated:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/coybit/coybit.github.io/raw/master/assets/bash/bash-tree.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;But when you enter:&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; A &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; B &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;the parset generates this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;command&lt;/code&gt; object:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/coybit/coybit.github.io/raw/master/assets/bash/bash-cm_connection.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The first difference you have probably noticed is the value of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;type&lt;/code&gt; field. This value shows that the union part of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;command&lt;/code&gt; structure represents a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;connection&lt;/code&gt; structure which is:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* Structure used to represent the CONNECTION type. */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ignore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;            &lt;span class=&quot;cm&quot;&gt;/* Unused; simplifies make_command (). */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;COMMAND&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;        &lt;span class=&quot;cm&quot;&gt;/* Pointer to the first command. */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;COMMAND&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;second&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;        &lt;span class=&quot;cm&quot;&gt;/* Pointer to the second command. */&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;        &lt;span class=&quot;cm&quot;&gt;/* What separates this command from others. */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CONNECTION&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;connection&lt;/code&gt; command has two sub-commands, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;first&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;second&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I have drawn what the parser generates:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/coybit/coybit.github.io/raw/master/assets/bash/bash-list.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;By continuing debugging, we will see that how a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;connection&lt;/code&gt; command gets evaluated is different from how a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cond_com&lt;/code&gt; command does. Actually, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cond_com&lt;/code&gt; has a tree structure ( left node, right node and op ) and is made of the expression according to the  Operator Precedence table, but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;connection&lt;/code&gt; commands are more like a list ( it has first and second sub-command ) and gets evaluated from left to right given these two principles:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;command1 &amp;amp;&amp;amp; command2
Command2 is executed if, and only if, command1 returns an exit status of zero.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;command1 |│ command2
Command2 is executed if and only if command1 returns a non-zero exit status.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In our example:&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; A &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; B &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[[ A == B ]]&lt;/code&gt; is evaluated. It is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt;, so according to principle #1 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ls&lt;/code&gt; will be ignored.&lt;/li&gt;
  &lt;li&gt;Because the result of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[[ A == B ]] &amp;amp;&amp;amp; ls&lt;/code&gt; was false, according to princple #2, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd&lt;/code&gt; will be executed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But what about the other example:&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; A &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; B &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ol&gt;
  &lt;li&gt;According to the generated tree, the expression is made of two sub-expression with the same precedence, so they gets evaluated from left to right:
 a. exp1: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A == B &amp;amp;&amp;amp; ls&lt;/code&gt;
 b. exp2: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exp1&lt;/code&gt; is made of two sub-expression with the same precedence, so they gets evaluated from left to right:
 a. exp1.1:  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A == B&lt;/code&gt;
 b. exp1.2:  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ls&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exp1.1&lt;/code&gt; is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt;. So the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exp1&lt;/code&gt; is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exp2&lt;/code&gt; gets evaluated.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As you see, the result of both of these two examples are the same.&lt;/p&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;p&gt;In spite of my first guest, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;||&lt;/code&gt; in a conditional expression is not the same as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp;&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;||&lt;/code&gt; in a list command. They get parsed and evaluated differently, but most of the time, the results are the same.&lt;/p&gt;</content><author><name></name></author><category term="bash" /><summary type="html">Question Last week when I was looking at a bash script file, I saw this line: [[ $FOLDER_NAME == &quot;ios&quot; ]] &amp;amp;&amp;amp; lib=&quot;lib-osx-amd64&quot; || lib=&quot;lib-linux32&quot; I’m not a bash expert, so this line caught my attention. At first, I thought what A &amp;amp;&amp;amp; B || C does is similar to what A ? B : C in many programming languages does. It takes a few hours of debugging, reading and thinking to realize this hypothesis was wrong!</summary></entry></feed>