<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Igor Guzak on Medium]]></title>
        <description><![CDATA[Stories by Igor Guzak on Medium]]></description>
        <link>https://medium.com/@igor04?source=rss-7f41be0f700d------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*hsdIQ1cXrsraWMo8a9vyLA.jpeg</url>
            <title>Stories by Igor Guzak on Medium</title>
            <link>https://medium.com/@igor04?source=rss-7f41be0f700d------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Mon, 11 May 2026 09:42:53 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@igor04/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Ruby access control — Protected]]></title>
            <link>https://medium.com/@igor04/ruby-access-control-protected-11cc05cede0?source=rss-7f41be0f700d------2</link>
            <guid isPermaLink="false">https://medium.com/p/11cc05cede0</guid>
            <category><![CDATA[ruby]]></category>
            <dc:creator><![CDATA[Igor Guzak]]></dc:creator>
            <pubDate>Sun, 15 Aug 2021 17:28:55 GMT</pubDate>
            <atom:updated>2021-08-15T17:40:32.703Z</atom:updated>
            <content:encoded><![CDATA[<h3>Ruby access control — Protected</h3><p>It’s easy to talk about public or private type of access control, because it’s obvious that public allows everything while private allows access only from within the same kind of objects (inherited). What about protected it’s quite different and some behavior of it could be surprising even for experienced ruby programmers, so make sure that you know it;)</p><pre>class Person<br>  attr_reader :address</pre><pre><strong>  protected :address</strong><br> <br>  def initialize(address)<br>    @address = address<br>  end<br>  <br>  def send_invitation_to(<strong>person</strong>)<br>    &quot;Sending invitation to &#39;#{<strong>person.address</strong>}&#39;&quot;<br>  end<br>end</pre><pre>igor = Person.new(&#39;Ukraine&#39;)<br>peter = Person.new(&#39;Germany&#39;)</pre><pre><strong>peter.address</strong> <em># =&gt; NoMethodError (protected method `address&#39; called for #&lt;Person:0x0000559e29f7ae50 @address=&quot;Germany&quot;&gt;)<br></em><strong>igor.send_invitation_to(peter)</strong><em> # =&gt; &quot;Sending invitation to &#39;Germany&#39;&quot;</em></pre><p>As you can see we have no access from outside to peter.address but when we try access it from within the same kind of instance where it was defined as protected then it works just fine. But you still need to be careful in place of polymorphism because if protected method was redefined then it will be no longer available for instances produced by parent class:</p><pre>class VeryImportantPerson &lt; Person<br>  <strong>protected</strong><br>  <br>  def address<br>    @address<br>  end<br>end</pre><pre>vip = VeryImportantPerson.new(&#39;France&#39;)<br><strong>vip.send_invitation_to(igor)</strong> <em># =&gt; &quot;Sending invitation to &#39;Ukraine&#39;&quot;</em><br><strong>igor.send_invitation_to(vip)</strong> <em># =&gt; NoMethodError (protected method `address&#39; called for #&lt;VeryImportantPerson:0x0000564a6ca9af58 </em><a href="http://twitter.com/address"><em>@address</em></a><em>=&quot;France&quot;&gt;)</em></pre><p>The same is true for class methods with only difference that protected methods as all other class related stuff is located in <a href="https://medium.com/@igor04/ruby-metaclass-eigenclass-singleton-af5274c2488c">Metaclass</a>, so could be accessed only from within the same kind of Metaclasses.</p><p>There is still the issue with class methods access control which beginners are tending to do:</p><pre>class First<br>  <strong>protected</strong></pre><pre>  def <strong>self</strong>.info<br>    &quot;some protected info - #{object_id}&quot;<br>  end<br>end</pre><pre><strong>First.info</strong> <em># =&gt; &quot;some protected info - 180&quot;</em></pre><p>First does not protect info method simply because protected does not affect class methods (which are located in <a href="https://medium.com/@igor04/ruby-metaclass-eigenclass-singleton-af5274c2488c">Metaclass</a>) and has effect only for methods which are defined for instances and if we need our class methods to be protected then we need to define them as protected in <a href="https://medium.com/@igor04/ruby-metaclass-eigenclass-singleton-af5274c2488c">Metaclass</a>.</p><pre>class Second<br>  class &lt;&lt; self<br>    <strong>protected</strong></pre><pre>    def info<br>      &quot;some protected info - #{object_id}&quot;<br>    end<br>  end<br>end</pre><pre><strong>Second.info</strong> <em># =&gt; NoMethodError (protected method `info&#39; called for Second:Class)</em></pre><p>Access control methods itself are private and could be used within class definition, but with send method we still could invoke private methods, so we could make our First.info protected without even opening <a href="https://medium.com/@igor04/ruby-metaclass-eigenclass-singleton-af5274c2488c">Metaclass</a>.</p><pre>First.singleton_class.send(:protected, :info)</pre><pre><strong>First.info</strong> <em># =&gt; NoMethodError (protected method `info&#39; called for First:Class)</em></pre><p>As you already know protected attributes could be accessed only from same kind of instances and instances produced by some classes have no relation to their Metaclasses, so there is no ability to access protected attributes of instance from within class methods or access protected class methods from within instances produced by it. Of course we have send which ignore access control and requires additional attention in places where it’s used, but attention is quite limited and valuable, so if you just need dynamically access public attributes and not violate access control, please use public_send ;)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=11cc05cede0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ruby Service object]]></title>
            <link>https://medium.com/@igor04/ruby-service-object-cd64dbe986aa?source=rss-7f41be0f700d------2</link>
            <guid isPermaLink="false">https://medium.com/p/cd64dbe986aa</guid>
            <category><![CDATA[ruby]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Igor Guzak]]></dc:creator>
            <pubDate>Tue, 28 Apr 2020 17:49:19 GMT</pubDate>
            <atom:updated>2020-05-01T08:42:10.182Z</atom:updated>
            <content:encoded><![CDATA[<p>What is a Service object? — First of all, it is an object that serves some needs. Such an object could be an application hosted on own server(s) and be a part of a network or it could be an object inside your single application. In both cases, we need to care about the granularity of our services and interface which allows us to interact with them in one or another way. In this post, I’ll try to clarify how service object could look like and what interfaces it would be good to support.</p><blockquote>Service object expects to perform single action, so there shouldn’t be more than one public method which could trigger it.</blockquote><p>Actually, there could be a number of methods but a service object as function in functional programming language expects to have a single entry point for executing it. If your service has more methods which perform some different things, then maybe it has more than one responsibility. So, if we have one method then it makes sense to name it call, not perform or execute because we already have call for <a href="https://medium.com/@igor04/ruby-lambda-proc-block-a13d13883b9b">lambda, proc, block</a> invocation and they all are about single action. The more obvious benefit is that we could use our services interchangeably with <a href="https://medium.com/@igor04/ruby-lambda-proc-block-a13d13883b9b">lambdas, proc, block</a>. But before we will dive into it, we need to clarify what kind of service objects we could have.</p><h4>1. Service class</h4><pre>class PrintService<br>  def self.call(value)<br>    puts value<br>  end<br>end</pre><pre>PrintService.call(&#39;well&#39;) <em># =&gt; &#39;well&#39;</em><br>PrintService.(&#39;well&#39;) <em># =&gt; &#39;well&#39;</em></pre><p>It’s the simplest service object which could be, it doesn’t require the creation of a new instance of himself. I think such kind of service objects make sense while it is simple and you didn’t start creating more class methods and passing arguments around, which brings us to the next type of service object.</p><h4>2. Service instance (+class compatible)</h4><pre>class MultiplyService<br>  def initialize(a, b)<br>    @a = a;<br>    @b = b;<br>  end<br>  <br>  def call<br>    @a * @b<br>  end<br>end</pre><pre>RandService.new(2, 2).call # =&gt; 4<br>RandService.new(2, 3).() # =&gt; 6</pre><p>Sometimes we need additional private methods in our service to make call method simpler and to avoid passing call method arguments down to other methods that perform some related work. Maybe later you will find out that some of these methods are ready to be service objects as well. But who wants additional new method invocation? — so it could make sense define a class method in such way:</p><pre>class MultiplyService<br>  def self.call(*args)<br>    new(*args).call<br>  end<br>end</pre><pre>MultiplyService.call(1, 3) <em># =&gt; 3</em><br>MultiplyService.(2, 2) <em># =&gt; 4</em></pre><p>Now our service has own instance but the interface for triggering it could be the same as in the previous case via invocation of call class method. At the same time service initialization using new and then multiple invocations of it also is possible, which could make sense for some cases like mutating state (side effects), or generating some kind of events like “ping”, but as our instance call method has no arguments we could introduce next type of service.</p><h4>3. Reusable Service instance (-class compatible)</h4><pre>class LogService<br>  def initialize(source)<br>    @source = source<br>  end<br>  <br>  def call(message)<br>    @source &lt;&lt; &quot;Info -- #{message}\n&quot;<br>  end<br>end</pre><pre>service = LogService.new(STDOUT)<br>%w[one two].map { |m| service.call(m) } <em># =&gt; Info -- one\n...</em></pre><p>The difference from the previous kind of service is that we split arguments between initialize and call in a way that we don’t want initialize new service on every invocation while only the target argument is changed but the whole service is still the same. As result we need to initialize service before it could be used, if you initialize it one every invocation then you don’t need to split arguments and use the previous type of service object, from the same point such service has no sense in class invocation method, because initialization and invocation expect to be done separately.</p><p>Now let&#39;s move back to our <a href="https://medium.com/@igor04/ruby-lambda-proc-block-a13d13883b9b">lambda, proc, block</a> and benefits of call method and why it happens that using our service as block requires us to do such things like: &amp;PrintService.method(:call)</p><h4>Service object to Proc</h4><p>Services defined previously have a method call so we could switch them with lambda or proc but just in a place where call method is invoked, but when we wont to pass our service object as block it doesn’t work:</p><pre>[1,2,3].map &amp;PrintService<br># =&gt; TypeError (wrong argument type PrintService (expected Proc))</pre><p>&amp; expects that there will be something which could be converted to proc, but our services just have a method call, so we need to fix it:</p><pre>module Service<br>  def to_proc<br>    method(:call).to_proc<br>  end<br>end</pre><pre>PrintService.extend(Service)<br>MultiplyService.extend(Service)<br>LogService.include(Service)</pre><pre>[1,2,3].map <strong>&amp;PrintService</strong> <em># =&gt; 1\n2\n3\n</em></pre><pre>log_service = LogService.new(STDOUT)<br>[1,2,3].map <strong>&amp;log_service</strong> <em># =&gt; Info -- 1\n...</em><br></pre><p>Now it looks better! So &amp; invoke to_proc on an object which is used with it, as a result we could extend our services with such a method and returns exactly what we need. In the case of LogService we extend the functionality of our service instance since it is not expected to be used as the service class. But were an example of MultiplyService? — move to the next section.</p><h4>Service object with currying</h4><pre>[1,2,3].map <strong>&amp;MultiplyService</strong> <em># =&gt; ArgumentError(given 1, expected 2)</em></pre><p>As expected we cannot iterate over our MultiplyService since it requires two arguments while map provide only one. For such kind of problem proc already has currying, so we just need to extend our services with such ability:</p><pre>module Service<br>  def [](*args)<br>    method(:call).curry.call(*args)<br>  end<br>end</pre><pre>[1,2,3].map <strong>&amp;MultiplyService[2]</strong> <em># =&gt; [2,4,6]</em></pre><p>I think square brackets are exactly what is needed since they are available for proc invocation in the same way as call, but in our implementation, we will have currying in place when not enough arguments are provided.</p><h4>Composition of Service Objects</h4><p>Since Ruby 2.6 we have the ability to build the composition of our Proc objects, so it looks normal to have such ability for our services as well:</p><pre>module Service<br>  def &gt;&gt;(service)<br>    method(:call).&gt;&gt;(service)<br>  end</pre><pre>  def &lt;&lt;(service)<br>    method(:call).&lt;&lt;(service)<br>  end<br>end</pre><pre>[1,2,3].map (MultiplyService[2] &gt;&gt; PrintService) # =&gt; 2\n4\n6\n</pre><p>It looks nice that we have such ability but in terms of performance, it’s not the same as direct invocation.</p><p><strong>PS: </strong>Ability to interact with your service object as with Proc doesn’t mean that you need to use it instead of Proc, as already mentioned they both are about single action so it could even make sense just to use Proc instead of service objects.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cd64dbe986aa" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ruby “main”]]></title>
            <link>https://medium.com/@igor04/ruby-main-789ff58320f?source=rss-7f41be0f700d------2</link>
            <guid isPermaLink="false">https://medium.com/p/789ff58320f</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[ruby]]></category>
            <dc:creator><![CDATA[Igor Guzak]]></dc:creator>
            <pubDate>Sat, 18 Apr 2020 16:03:27 GMT</pubDate>
            <atom:updated>2020-04-18T16:03:27.116Z</atom:updated>
            <content:encoded><![CDATA[<p>Maybe you’ve noticed that Ruby scripts are executed in some special space or scope which is called “main”:</p><pre>inspect <em># =&gt; &quot;main&quot;</em></pre><p>So, let&#39;s try to clarify what it is.</p><pre>self.class <em># =&gt; Object</em><br>method(:inspect).owner <em># =&gt; #&lt;Class:#&lt;Object:0x000055bd67f9dd58&gt;&gt;</em><br>method(:inspect).owner == singleton_class <em># =&gt; </em><strong><em>true</em></strong></pre><p>It looks like main is an instance of Object C<a href="https://medium.com/@igor04/ruby-class-instance-8d9cada56ba6">lass instance</a>, while a method inspect is defined as it’s <a href="https://medium.com/@igor04/ruby-metaclass-eigenclass-singleton-af5274c2488c">Singleton</a>:</p><pre>def self.inspect<br>  &quot;my-main&quot;<br>end</pre><pre>inspect <em># =&gt; &quot;my-main&quot;</em></pre><pre>singleton_class.instance_methods(false) <em># =&gt; [:inspect, :to_s]</em></pre><p>It’s expected behavior since Ruby check’s Singleton methods in the first place and just then instance methods defined by <a href="https://medium.com/@igor04/ruby-class-instance-8d9cada56ba6">Class instance</a> which produced it. So, if main is an instance produced by Object then what about instance variables?</p><pre>@instance_var = 1<br>@instance_var <em># =&gt; 1</em></pre><p>Works as expected, but what about regular methods defined with def which we could define without using Class scope? Maybe it would be better do not have such ability, so every method would be possible to define only in the context of Class instance, but currently, we have such ability, so let&#39;s check it:</p><pre>def my_method<br>  &#39;method in main scope&#39;<br>end</pre><pre>my_method <em># =&gt; &#39;method in main scope&#39;</em></pre><p>This is the place where main is no more just instance produced by Object Class instance, but something more, because we could add methods to already existed instance without using Singleton or Object Class instance, so it works like we are in the scope of Object Class instance and defining regular instance method:</p><pre>method(:my_method).owner  <em># =&gt; Object</em><br>Object.instance_methods.include?(:my_method) <em># =&gt; </em><strong><em>true</em></strong></pre><pre>Object.new.my_method <em># =&gt; Error: </em><strong><em>private</em></strong><em> method `my_method&#39; called</em></pre><p>As you could see, it’s not a regular instance method, it’s private, so methods defined in main scope are defined as a private methods of Object Class instance. One more thing which works in main scope as in Class instance scope are constants:</p><pre>CONST = &#39;constant&#39; <em># =&gt; defined like in class scope</em><br>Object.const_defined?(:CONST) <em># =&gt; true</em><br>Object::CONST <em># =&gt; &quot;constant&quot;</em></pre><p>Maybe there are more examples which could demonstrate that main is not just instance produced by Object Class instance, but also as we already see it has some special power which is available in Class scope. Additionally, we could check few more methods which extends our main instance:</p><pre>singleton_class.private_instance_methods(false)<br><em># =&gt; [:public, :private, :include, :using, :define_method]</em></pre><p>In the case of using IRB it’s common to see irb(main) &gt; but you could change it redefining inspect and to_s as we did above, but more interesting is that you could change scope using cb command and jump around from one context to another, but remember that main is not just simple Object instance;)</p><pre><em>irb(main)</em><strong><em>&gt;</em></strong> singleton_class.remove_method :to_s, :inspect<br><em>irb(#&lt;Object:0x000055b6fc5e1d58&gt;)</em><strong><em>&gt;</em></strong> cb Object<br><em>irb(Object)</em><strong><em>&gt;</em></strong> cb Object.new<br><em>irb(#&lt;Object:0x00005612b111dd38&gt;)</em><strong><em>&gt; </em></strong></pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=789ff58320f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ruby lambda, proc, block]]></title>
            <link>https://medium.com/@igor04/ruby-lambda-proc-block-a13d13883b9b?source=rss-7f41be0f700d------2</link>
            <guid isPermaLink="false">https://medium.com/p/a13d13883b9b</guid>
            <category><![CDATA[ruby]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Igor Guzak]]></dc:creator>
            <pubDate>Sun, 16 Feb 2020 16:23:59 GMT</pubDate>
            <atom:updated>2020-02-18T09:08:20.719Z</atom:updated>
            <content:encoded><![CDATA[<p>If you are not familiar with Ruby then you could be quite scared by multiple articles about lambda, proc, block and different styles of how they could be defined and used. If you are familiar with them you may already know that there is nothing special but something still could be missed, so I will try to make it cleaner and fill some gaps.</p><h4>How we define our ‘proc’ and ‘lambda’</h4><pre>my_proc = <strong>Proc</strong>.new { p &#39;Hello!&#39; } # =&gt; #&lt;Proc:<a href="mailto:0x00005560b0829b80@proc.rb">0x000055</a>...&gt;<br>my_proc<strong> = proc</strong> { p &#39;Hello!&#39; }     # =&gt; #&lt;Proc:<a href="mailto:0x00005560b0829a18@proc.rb">0x000055...&gt;</a></pre><pre>my_lambda = <strong>lambda</strong> { p &#39;Hello!&#39; } # =&gt; #&lt;Proc:<a href="mailto:0x00005560b0829900@proc.rb">0x000055...</a> (lambda)&gt;<br>my_lambda = <strong>-&gt;</strong> { p &#39;Hello!&#39; }     # =&gt; #&lt;Proc:0x000055<a href="mailto:0x00005560b0829900@proc.rb">...</a> (lambda)&gt;</pre><p>You could replace {} with do end and have the same results but with a pretty different look and if you will mix these styles with no reasons then it will be just harder to read and one more way to frighten newcomers. So, if you have multiline definition then do end could be better than {}, while for inline definitions {} is more appropriate, BTW there is no relation between lambda and {} as between Proc and do end.</p><p>In which way to construct — Proc.new is just an explicit way of creating new proc as an instance of the Proc <a href="https://medium.com/@igor04/ruby-class-instance-8d9cada56ba6">class instance</a> and almost never used on practice, so if we need proc then just use proc keyword but even this is a rare case simply because Ruby has a more elegant way of constructing proc and it has name block to which we will return later. What about lambda keyword it’s mostly used when we have a multiline definition with do end, while for inline definitions we have -&gt; {}, but at some project -&gt; {} could be used even for multiline definitions while lambda in conjunction with do end could be avoided at all.</p><h4>What about invocation:</h4><pre>greeting = &quot;Hello&quot;<br>my_lambda = <strong>-&gt;</strong> (name) { &quot;#{greeting} #{name}!&quot; }<br>my_lambda<strong>.call(</strong>&#39;John&#39;<strong>)</strong> # =&gt; &#39;Hello John!&#39;</pre><pre>greeting = &quot;Aloha&quot;<br>my_lambda<strong>.call(</strong>&#39;John&#39;<strong>)</strong> # =&gt; &#39;Aloha John!&#39;<br>my_proc<strong>.(</strong>&#39;John&#39;<strong>)</strong>       # =&gt; &#39;Aloha Hello!&#39;<br>my_proc<strong>[</strong>&#39;John&#39;<strong>]</strong>        # =&gt; &#39;Aloha Hello!&#39;</pre><p>In the same way both proc and lambda scope outer variables, as a result of changing greeting we changed behavior. At the same time, there are few ways of invocation, while .call is the most common and frequently used way, some projects could follow .() style and have:</p><pre>add = -&gt; (a) { -&gt; (b) { a + b } }</pre><pre>add.(1).(2) # =&gt; 3</pre><h4>What is the difference between ‘proc’ and ‘lambda’?</h4><p>You may already noticed from the definition part that lambda is just some kind of Proc but there is a difference in place of receiving arguments and returning a value, while Proc is a special kind of beast, lambda could be simply treated as an anonymous method because it has the same behavior for incoming arguments and return as a regular method defined with def keyword:</p><pre>greeting = <strong>-&gt;</strong> (name) { <strong>return</strong> &quot;Hello #{name}!&quot; }<br>greeting.call(&#39;John&#39;) # =&gt; Hello John!<br>greeting.call() # =&gt; ArgumentError (wrong number of arguments ...</pre><p>But why Proc is something special? — Simply because it behaves in a different way in comparison with regular methods, it’s not restricted to arguments and return not just return some value from inside of Proc, it returns value out from scope it’s <strong>defined</strong> in:</p><pre>greeting = <strong>proc</strong> { |name| <strong>return</strong> &quot;Aloha John!&quot; if name == &#39;John&#39; }<br>greeting.call(&#39;Bond&#39;) # =&gt; nil<br>greeting.call(&#39;John&#39;) # =&gt; LocalJumpError (unexpected return)<br><br>def perform(name)<br>  greeting = <strong>proc</strong> { |name| <strong>return</strong> &quot;Aloha John!&quot; if name == &#39;John&#39; }<br>  greeting.call(name)<br>  &quot;Hello #{name}!&quot;<br>end</pre><pre>perform(&#39;Bond&#39;) # =&gt; &quot;Hello Bond!&quot;<br>perform(&#39;John&#39;) # =&gt; &quot;Aloha John!&quot;</pre><p>As you can see, greeting returns value right from perform in which it was defined. Just as a note — last value in lambda or proc will be returned as a result of .call invocation, so use return when it makes sense, which is not about previous example, a better example of immediate return could be:</p><pre>class Array<br>  def has?(target)<br>    each { |item| <strong>return</strong> true if item == target }<br>    false<br>  end<br>end</pre><pre>[1,2,3,4].has?(2) # =&gt; true<br>[1,2,3,4].has?(5) # =&gt; false</pre><p>So, each is a method which iterates through every item of array with invocation of code in the curly brackets for every item in array and in the place where item equal to target we return true right from has? method and only in case if nothing was matched during iteration then false will be returned.</p><h4>What about ‘block’?</h4><p>In the above example, you may already notice something similar to proc or lambda, something in curly brackets which was passed to each method without proc or lambda keywords — block. It’s one of the things Matz is proud of, thing which is on every corner in Ruby world, no keywords needed no constructors only <em>block</em> of code in {} or do end and named block, how it could be named in a better way?;) Ok, it’s cool, but we already have proc and lambda why do we need something new? — It’s not new, it’s just simple Proc but constructed in place of method invocation in an elegant way, but since it’s not a regular argument which we are passing into the method, it needs to be handled differently:</p><pre>def perform_block(<strong>&amp;</strong>block)<br>  block.call if block<br>end</pre><pre># or</pre><pre>def perform_block<br>  <strong>yield</strong> if <strong>block_given?</strong><br>end</pre><pre>perform_block # =&gt; nil<br>perform_block { &quot;Hello!&quot; } # =&gt; &quot;Hello!&quot;</pre><p>As you can see we need a special sign &amp; for argument which will receive block and then we could simply access our variable which will contain our proc instance, also we could use a special method yield for invocation and block_given to check if the block was passed. The fact that we have block doesn’t mean that we could not create proc manually and pass it to method explicitly, even more, we could convert proc and lambda to block argument:</p><pre>def perform_proc(my_proc = nil)<br>  my_proc.call if my_proc<br>end</pre><pre>greeting = proc { &quot;Hello!&quot; }<br>perform_proc(greeting)   # =&gt; &quot;Hello!&quot;</pre><pre><strong>perform_block</strong>(<strong>&amp;</strong>greeting) # =&gt; &quot;Hello!&quot;<br><strong>perform_block</strong>(<strong>&amp;</strong>-&gt; { &quot;Convert lambda to block&quot; })</pre><blockquote>Conversion of lambda to method&#39;s block argument doesn’t mean that we change its behavior, so yield or block.call will invoke the same lambda which we pass to the method as block</blockquote><h4>More ways to ‘return’</h4><p>if we still need immediate return of some value from proc without returning from the scope in which it was defined we could use next keyword which for lambda works the same as return:</p><pre>class Array<br>  def replace(target_value, new_value)<br>    map do |item|<br>      <strong>next</strong> new_value if item == target_value<br>      item<br>    end<br>  end<br>end</pre><pre>[1, 2, 3].replace(2, &#39;X&#39;) # =&gt; [1, &quot;X&quot;, 3]</pre><p>map — is method which iterates over array in the same way as each with a difference that it collects results from each iteration, so we don’t need return from replace method itself, we only need return value from proc and continue iteration and next does exactly what we need. Of course, we could avoid next in the above example via using simple condition but in complex cases next as part of a “guard clause<em>”</em> could be simpler.</p><p>So with proc we could return value from the scope where it was defined using return, we could simply return value from inside of proc using next, but what about returning value from the scope where it was invoked not defined?</p><pre>def greeting(<strong>&amp;</strong>block)<br>  &quot;Hello #{block.call}!&quot;<br>end</pre><pre>greeting { &#39;John&#39; }        # =&gt; &#39;Hello John!&#39;<br>greeting { <strong>next</strong> &#39;John&#39; }   # =&gt; &#39;Hello John!&#39;<br>greeting { <strong>return</strong> &#39;Ups&#39; }  # =&gt; LocalJumpError (unexpected return)<br>greeting { <strong>break</strong> &#39;Bye!&#39; }  # =&gt; &#39;Bye!&#39;</pre><blockquote>While break inside block works fine, you could be quite disappointed to notice that it doesn’t work in the same way for proc and produce LocalJumpError (break from proc-closure) no matter where you call it. It’s strange since block is just the same proc and expect to have the same behavior, so for me it sounds like language issue.</blockquote><p>What about break with lambda we just have one more way to return ;)</p><pre>def greeting(my_lambda)<br>  &quot;Hello #{my_lambda.call}!&quot;<br>end</pre><pre>greeting -&gt; { &#39;John&#39; }                 # =&gt; &#39;Hello John!&#39;<br>greeting -&gt; { <strong>next</strong> &#39;John&#39; }            # =&gt; &#39;Hello John!&#39;<br>greeting -&gt; { <strong>return</strong> &#39;again&#39; }         # =&gt; &#39;Hello again!&#39;<br>greeting -&gt; { <strong>break</strong> &#39;one more time&#39; }  # =&gt; &#39;Hello one more time!&#39;</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a13d13883b9b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ruby variable or method]]></title>
            <link>https://medium.com/@igor04/ruby-variable-or-method-ac6814b4e8b1?source=rss-7f41be0f700d------2</link>
            <guid isPermaLink="false">https://medium.com/p/ac6814b4e8b1</guid>
            <category><![CDATA[ruby]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Igor Guzak]]></dc:creator>
            <pubDate>Sun, 26 Jan 2020 17:52:07 GMT</pubDate>
            <atom:updated>2020-01-26T17:52:07.706Z</atom:updated>
            <content:encoded><![CDATA[<p>It’s a well-known fact that Ruby language has no requirements for parenthesis, but we also could have variables and methods with identical names:</p><pre>something <br># =&gt; NameError (undefined local variable or method `something` ...</pre><pre>def something; :method; end<br>something() # =&gt; :method<br>something   # =&gt; :method</pre><pre>something = :variable<br>something() # =&gt; :method<br>something   # =&gt; :variable</pre><p>So, in the first place, we are looking for a variable and just then for a method with the same name. It’s more explicit when the method is invoked with parenthesis, but there is no reason for it:</p><pre>user.update(first_name: &#39;John&#39;)</pre><p>What is user in the above example? Yes, it could be variable or method but in both cases, we expect some value, no matter how it is delivered. In some cases, during refactoring, we simply could just replace a variable with the method or replace method with inline variable without additional changes.</p><p>One more interesting case is the situation with constant variables which are used for <a href="https://medium.com/@igor04/ruby-class-instance-8d9cada56ba6">Class instances</a> and regular constants LIKE_THIS:</p><pre>ONE = 1<br>def ONE<br>  1.0<br>end</pre><pre>ONE   # =&gt; 1<br>ONE() # =&gt; 1.0</pre><pre># but</pre><pre>def TWO<br>  2.0<br>end</pre><pre>TWO   # =&gt; NameError (uninitialized constant TWO)<br>TWO() # =&gt; 2.0</pre><p>As you can see there is a difference between regular variable and constant variables, there is no lookup by methods, so even if you have a method with the same name as constant it will not be invoked until you explicitly use parenthesis or pass arguments to it. While we could have method names similar to constant names it looks strange, but situation with constants used for Class instances are different:</p><pre>def Person(first_name, last_name)<br>  Person.new(first_name, last_name)<br>end</pre><pre>class Person<br>  def initialize(first_name, last_name)<br>    @first_name = first_name<br>    @last_name = last_name<br>  end<br>end</pre><pre>Person(&quot;Ricky&quot;, &quot;Martin&quot;) # =&gt; #&lt;Person:....&gt;</pre><p>In the above example, we use a method with the same name as our Class instance variable name to perform the creation of new instances which may have no much sense, but there are more useful examples — in Ruby, we have such methods like Array() which tries to invoke to_ary or to_a on argument passed to it, so it could be used for conversion. Also, we could get some example from <a href="https://dry-rb.org/">dry-rb</a>, where we have such methods for generating new Class instances:</p><pre>module Dry<br>  def self.Struct(attributes = EMPTY_HASH, &amp;block)    <br>    Class.new(Dry::Struct) do<br>      attributes.each { |a, type| attribute a, type }          <br>      module_eval(&amp;block) if block<br>    end<br>  end<br>end</pre><pre>User = Dry.Struct(name: Types::String, age: Types::Integer)</pre><pre># equal to:</pre><pre>class User &lt; Dry::Struct<br>  attribute :name, Types::String<br>  attribute :age, Types::Integer<br>end</pre><p>If a method is instantly invoked without parenthesis then how we could get reference on it and pass around? How we could invoke methods in different contexts? Is it possible at all? — Yes, there is a Class instances <a href="https://ruby-doc.org/core-2.5.3/Method.html">Method</a> and <a href="https://ruby-doc.org/core-2.2.0/UnboundMethod.html">UnboundMethod</a> which provide such abilities:</p><pre>bounded_push = [1,2].method(:push) # =&gt; #&lt;Method: Array#push&gt;<br>bounded_push.call(3)               # =&gt; [1,2,3]</pre><pre>unbound_push = bounded_push.unbind # =&gt; #&lt;UnboundMethod: Array#push&gt;<br>unbound_push.bind([&#39;a&#39;]).call(&#39;b&#39;) # =&gt; [&#39;a&#39;,&#39;b&#39;]</pre><p>As you can see, we can get “reference” on method and invoke later, at the same time we could unbind method from one context and bind it to another instance.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ac6814b4e8b1" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ruby Metaclass, Eigenclass, Singleton]]></title>
            <link>https://medium.com/@igor04/ruby-metaclass-eigenclass-singleton-af5274c2488c?source=rss-7f41be0f700d------2</link>
            <guid isPermaLink="false">https://medium.com/p/af5274c2488c</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[ruby]]></category>
            <dc:creator><![CDATA[Igor Guzak]]></dc:creator>
            <pubDate>Wed, 08 Jan 2020 16:46:10 GMT</pubDate>
            <atom:updated>2020-01-09T08:00:54.026Z</atom:updated>
            <content:encoded><![CDATA[<p>In <a href="https://medium.com/@igor04/ruby-class-instance-8d9cada56ba6">the previous post</a> about Class I’ve described the fact that it’s instance and now it’s time to describe how we define new functionality for such instances and instances which they could produce. Example:</p><pre>class Person<br>  def initialize(first_name, last_name)<br>    @first_name = first_name<br>    @last_name = last_name<br>  end<br> <br>  def full_name<br>    &quot;#{@first_name} #{@last_name}&quot;<br>  end<br>end</pre><pre>Person.instance_methods(false) # =&gt; [:full_name]</pre><pre>person = Person.new(&quot;Bob&quot;, &quot;Martin&quot;)<br>person.full_name # =&gt; Bob Martin</pre><p>As we can see there is a definition of Class instance Person which describe functionality of instances it could produce. Method new is part of Class implementation which is responsible for creating new instance and after such instance is created the private method initialize will be invoked on it. So, both methods initialize and full_name are called instance methods simply because they are available for instances produced by Person, but in the same way method new is instance method of Person instance produced by Class, such methods, available for Class instances we call simply as “class methods”.</p><p>So, if we need more functionality for instances produced by Person we could define it in place of creation Person instance, but how we could add some functionality to Person instance itself which is produced by Class instance? Do we need to define it in place of creation Class instance? but where is such a place? — The answer is that we don’t need to modify Class instance to add functionality to the single instance produced by it, such as Person, at list because we need to define some functionality only for Person instance not for all instances produced by Class instance. The solution is that<strong> every instance has one more instance behind it</strong> and it is linked to the initial one and could be used for such purpose:</p><pre>class Person<br>  def self.info<br>    &quot;Some description&quot;<br>  end<br>end</pre><pre># or</pre><pre>class Person<br>  class &lt;&lt; self<br>    def info<br>      &quot;Some description&quot;<br>    end<br>  end<br>end</pre><pre># or</pre><pre>def Person.info<br>  &quot;Some description&quot;<br>end</pre><pre># or</pre><pre>class &lt;&lt; Person<br>  def info<br>    &quot;Some description&quot;<br>  end<br>end</pre><pre>Person.singleton_class.instance_methods(false) # =&gt; [:info]</pre><pre>Person.info # =&gt; Some description</pre><p>So, if we need some “class methods” for our Class instances such as Person instance then we use the second instance behind it which is called as Metaclass or Eigenclass or Singleton.</p><pre>def Person.new; end</pre><pre>Person.new # =&gt; nil</pre><p>As you can see we redefine new method with our own implementation located in Metaclass. The next question could be — if every instance has some instance behind it then how it works when we try it on instances different from Class instances?</p><pre>bob = Person.new(&quot;Bob&quot;, &quot;Martin&quot;)<br>ricky = Person.new(&quot;Ricky&quot;, &quot;Martin&quot;)</pre><pre>def bob.full_name<br>  &quot;Robert Cecil #{@last_name}&quot;<br>end</pre><pre># or</pre><pre>class &lt;&lt; bob<br>  def full_name<br>     &quot;Robert Cecil #{@last_name}&quot;<br>  end<br>end</pre><pre>bob.full_name # =&gt; Robert Cecil Martin<br>ricky.full_name # =&gt; Ricky Martin</pre><p>So, we redefine bob instance full_name method definition with custom implementation placed in Metaclass which just highlight the way how it’s linked to initial instance, at the same time instance ricky didn’t change behaviour simply because it has own Metaclass. While this works fine there is no much reason to use it and confuse everyone why instances produced by the same Person instance have different behaviour, so remember that it’s solution to have different behaviour for instances produced by Class instance such as Person, File, Dir, etc. which are produced from the same Class instance but needs different functionality.</p><p>If there is still a need to define some functionality which need to be available for all Class instances or we need to change already existed Class instance then we could simply “re-open” it, but there is no much sense in such monkey patching, which could bring a lot of pain:</p><pre>class Class<br>  def info<br>    &quot;#{self.name} instance produced by Class instance&quot;<br>  end<br>end</pre><pre>class Person<br>  def full_name<br>    &quot;patched full_name&quot; # original method need to be updated instead<br>  end<br>end</pre><pre>Person.info # =&gt; Person instance produced by Class instance<br>Person.new(nil, nil).full_name # =&gt; patched full_name</pre><p>Again there is some special cases with “unique” values such as symbols and numbers which doesn’t have additional instance behind it because there is no much sense to define specific functionality only for single symbol or number, at same time we have such ability for true, false, nil values:</p><pre>def true.info; end</pre><pre>a = :something<br>def a.info; end<br># =&gt; TypeError (can&#39;t define singleton)</pre><p>From the message, it’s obvious that we try to define Metaclass but it was rejected, so Metaclasses are created automatically only for instances produced by Class instance, while for other instances Metaclasses are created when they are needed.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=af5274c2488c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ruby Class instance]]></title>
            <link>https://medium.com/@igor04/ruby-class-instance-8d9cada56ba6?source=rss-7f41be0f700d------2</link>
            <guid isPermaLink="false">https://medium.com/p/8d9cada56ba6</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[ruby]]></category>
            <dc:creator><![CDATA[Igor Guzak]]></dc:creator>
            <pubDate>Sun, 29 Dec 2019 10:56:13 GMT</pubDate>
            <atom:updated>2021-08-12T11:52:14.761Z</atom:updated>
            <content:encoded><![CDATA[<p>It’s well-known fact that everything in Ruby is an object or in other words instance of something, but it still could be confusing how class definitions and instances produced by them are about the same. In this post, I will try to make it cleaner.</p><pre>class Person; end</pre><p>This is the way how we create class in Ruby via using language syntax. At the same time, it is just a common way we create a new instance of Class and assigning it to Person variable, which is equal to:</p><pre>Person = Class.new</pre><p>Only instances of Class have abilities to create new instances:</p><pre>person = Person.new</pre><p>And someone could raise a question — if only instances produced by Class have the ability to create new instances then how we could explain the ability of having Class.new and produce such instances too? So, there is a logical answer — Class is the instance of Class or itself;)</p><pre>person.class # =&gt; Person<br>Person.class # =&gt; Class<br>Class.class  # =&gt; Class</pre><pre>Class.object_id == Class.class.object_id # =&gt; true</pre><blockquote>The question of how Class could be an instance of them-self is rhetorical because it’s language implementation about which could be more discovered in <a href="https://github.com/ruby/ruby">Ruby source code</a>, also there is an awesome book <a href="https://www.amazon.com/Ruby-Under-Microscope-Illustrated-Internals/dp/1593275277">Ruby Under a Microscope: An Illustrated Guide to Ruby Internals</a>.</blockquote><p>Instances of Class we simply call “classes” as places of definitions for our instances which they could produce, at the same time we name our “classes” with capital letter as Person to highlight the fact that it’s Class instance, but as it’s still an instance it could have any name:</p><pre>person = Class.new # =&gt; #&lt;Class:0x00005614bb425718&gt;<br>Person = Class.new # =&gt; Person</pre><p>The difference is only the way how such instance represent/print itself, so if we will ignore such customization there will be no difference:</p><pre>Module.remove_method :inspect</pre><pre>Person # =&gt; #&lt;Class:0x0000563455a4c920&gt;<br>Class  # =&gt; #&lt;Class:0x000055a8aa2a1608&gt;</pre><p>Not every Class instances have the ability to create new instances due to global uniqueness:</p><pre>true.class # TrueClass<br>false.class # FalseClass<br>nil.class # NilClass<br>1.class # Integer<br>:something.class # Symbol</pre><pre>:something.object_id == :something.object_id # =&gt; true</pre><pre>Symbol.new(&#39;something&#39;) <br># =&gt; NoMethodError (undefined method `new&#39; for Symbol:Class)</pre><p>So, there is no sense in Symbol.new(&#39;something&#39;) simply because Symbol is not able to produce new instances one every invocation of new. The same is true for boolean and number instances which are globally unique, so instance of Integer such as 1 is always the same and there is no ability to create new 1</p><pre>Integer.remove_method :inspect</pre><pre>1 # =&gt; #&lt;Integer:0x0000000000000003&gt;<br>2 - 1 # =&gt; #&lt;Integer:0x0000000000000003&gt;</pre><p>Also, there is some special case with such Class instance as String which always produce new instances when it’s done explicitly, but when we use literals in conjunction with magic comment # frozen_string_literal the instance of string is reused (and it’s frozen so cannot be changed)</p><pre>String.new(&#39;a&#39;).object_id == String.new(&#39;a&#39;).object_id # =&gt; false<br>&#39;a&#39;.object_id == &#39;a&#39;.object_id # =&gt; <strong>false</strong></pre><pre># with magic comment which need to be placed on top of your .rb file<br># frozen_string_literal: true</pre><pre>String.new(&#39;a&#39;).object_id == String.new(&#39;a&#39;).object_id # =&gt; false<br>&#39;a&#39;.object_id == &#39;a&#39;.object_id # =&gt; <strong>true</strong></pre><p>Next to read:<strong> </strong><a href="https://medium.com/@igor04/ruby-metaclass-eigenclass-singleton-af5274c2488c"><strong>Ruby Metaclass, Eigenclass, Singleton</strong></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8d9cada56ba6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Prevent concurrent exception in Ohm/Redic]]></title>
            <link>https://medium.com/@igor04/prevent-concurrent-exception-in-ohm-redic-494cb8d66e10?source=rss-7f41be0f700d------2</link>
            <guid isPermaLink="false">https://medium.com/p/494cb8d66e10</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[ruby]]></category>
            <dc:creator><![CDATA[Igor Guzak]]></dc:creator>
            <pubDate>Sun, 17 Nov 2019 08:21:19 GMT</pubDate>
            <atom:updated>2019-11-17T08:21:19.002Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/550/1*M1DZazDaShTh_dDQVWXD2Q.png" /></figure><p>On one of the projects we catch a few exceptions in a short period of time which pointed to Ohm::Model<em> </em>objects with the message RuntimeError: not connected. <a href="https://github.com/soveran/ohm">Ohm</a> is a gem that provides objects mapping for Redis and the issue in the first place was fixed with some tweaks around Redis connections, but the reason for the issue was not clear. Why connection to Redis was not established? Or maybe the connection was lost due to some reasons? So it was decided to clarify where such exception comes from and why.</p><p>Ohm by default use <a href="https://github.com/amakawa/redic">Redi<strong>c</strong></a><strong> </strong>adapter for connecting to Redis. In Redi<strong>c</strong> client implementation <a href="https://github.com/amakawa/redic/blob/master/lib/redic/client.rb">lib/redic/client.rb</a>:</p><pre>def connect<br>  establish_connection unless connected?</pre><pre>  @semaphore.synchronize do<br>    yield<br>  end<br>rescue Errno::ECONNRESET<br>  @connection = false<br>  retry<br>end</pre><pre>def establish_connection<br>  begin<br>    @connection = Redic::Connection.new(@uri, @timeout)<br>  rescue StandardError =&gt; err<br>    raise err, “Can’t connect to: %s” % @uri<br>  end</pre><pre>  # ...<br>end</pre><p>we could see that StandardError exception during creation of connection instance is handled and exception message raised in result is different from what we’ve got, at the same time we handle Errno::ECONNRESET exception which expects to re-establish connection via retry if it to was lost. So, there is no reason why we could have RuntimeError: not connected, to clarify it we need dive dipper into implementation of Redic::Connection which simply wraps Hiredis::Connection from <a href="https://github.com/redis/hiredis-rb/">hredis-rb</a> gem.</p><p>Moving to Hiredis we could find<a href="https://github.com/redis/hiredis-rb/blob/master/lib/hiredis/connection.rb"> connection</a> implementation which by default lead us to Hiredis::Ext::Connection which wraps C implementation of <a href="https://github.com/redis/hiredis-rb/blob/master/ext/hiredis_ext/connection.c">connection</a> used for better performance and maps EOFError to already spotted in Redic exception Errno::ECONNRESET</p><pre>module Hiredis<br>  module Ext<br>    class Connection<br>      def read<br>        _read<br>      rescue ::EOFError<br>        raise Errno::ECONNRESET<br>      end<br>    end<br>  end<br>end</pre><p>moving down the line to C-extension we could find definition of read method <a href="https://github.com/redis/hiredis-rb/blob/master/ext/hiredis_ext/connection.c#L459">https://github.com/redis/hiredis-rb/blob/master/ext/hiredis_ext/connection.c#L459</a></p><pre>static VALUE connection_read(VALUE self) {<br>    // ....<br>    if (__get_reply(pc,&amp;reply) == -1)<br>        parent_context_raise(pc);</pre><p>which means that if a connection is lost we invokeparent_context_raise(pc) which expects that connection will be nullified and raised `EOFError` exception <a href="https://github.com/redis/hiredis-rb/blob/master/ext/hiredis_ext/connection.c#L61">https://github.com/redis/hiredis-rb/blob/master/ext/hiredis_ext/connection.c#L61</a></p><pre>static void parent_context_raise(redisParentContext *pc) {<br>    // ...<br>    parent_context_try_free(pc);<br>    // ...<br>    case REDIS_ERR_EOF:<br>        /* Raise native Ruby EOFError */<br>        rb_raise(rb_eEOFError,&quot;%s&quot;,errstr);</pre><p>as we already have seen EOFError later is transformed to Errno::ECONRESET and expect to be handled by Redic via creating a new connection, but if we will try to send data to such broken connection RuntimeError: not connected will be raised, so why the connection was not re-established but instead we send data to bad one? It happens simply because Redic establish_connection was involved outside of @semaphore.synchronize block which expects to sync all execution, as a result, while Errno::ECONNRESET was handled by one thread, others were trying to send data to old broken one and resulted in exception.</p><p>As conclusion, the issue was spotted and synchronization was fixed in PR to Redic <a href="https://github.com/amakawa/redic/pull/15">https://github.com/amakawa/redic/pull/15</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=494cb8d66e10" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Code Ownership and Code Review]]></title>
            <link>https://medium.com/@igor04/code-ownership-and-code-review-dff180744c0a?source=rss-7f41be0f700d------2</link>
            <guid isPermaLink="false">https://medium.com/p/dff180744c0a</guid>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Igor Guzak]]></dc:creator>
            <pubDate>Sun, 10 Nov 2019 10:20:51 GMT</pubDate>
            <atom:updated>2019-11-10T10:20:51.695Z</atom:updated>
            <content:encoded><![CDATA[<p>Every developer in a team and whole team together tend to work according to some best practices and produce high-quality code and one of such practices is <strong><em>Code Review</em></strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/550/1*1VF0VHvBDPdE1sxhIv4dHA.png" /></figure><p>If the quality is not one of the major points of the developing process then maybe you didn’t have a review process at all or it’s something formal which I think could happen in conjunction with <strong><em>Strong code ownership</em></strong> where developers allowed only to make changes to modules/areas they own. So there is only a single person who fully understands and is responsible for some area of the product. As for me, it’s not a team but individuals who leave in own worlds coordinated in some ways. There is no sense to talk about the quality of code produced in a such way, no matter how skilled is developer, because it will be alien code for the rest of the team. One more problem, in this case, is <strong><em>bus factor</em> </strong>equal to <strong>1</strong>, which means that if developer leaves the product there will be troubles with knowledge in areas they were responsible for.</p><p>Opposite situation is when team own the product with no borders between developers and this requires review, so developers will be aware of what code is introduced and how it is implemented, in case if there are questions to implementation they could be raised/discussed/resolved and just then accepted/merged. After PR is merged the code automatically becomes collective responsibility and has <strong><em>Collective ownership </em></strong>which means everyone in the team is responsible for it. Without review, we cannot have <strong><em>Collective ownership </em></strong>simply because no one wants to be responsible for something no one aware of. In this case expects that there is no bus factor but it could be true maybe only in case when all developers in a team have the same experience and all participate in every PRs, which is too ideal. While review is required for <strong><em>Collective ownership</em></strong> it doesn’t mean that every developer need perform PR review before it will be merged but it requires review from at list one/few developers who could represent collective ownership, it could be team/tech lead or senior developers it could be middle developer, but the main point is that whole team need to trust to this developer and accept responsibility for made decisions, so it needs to be experienced developers who can perform review in a way that there will be no questions why something bad was merged. If such questions are raised multiple times then maybe such developer cannot accept PRs at list alone, to stress such problem could be quite tricky, as example such team member could be a team lead, which has wide responsibilities and no time for writing code but still accepts PRs which will brings questions. So maybe it could make sense does not allow accept PRs for team members who don’t produce code and doesn’t work with code which they want to merge. At the same time, review should not be limited just to some developers and could be performed by anyone who wants to do it and could get value from it, learning new things, gain product expertise, etc.</p><p>In some cases <strong><em>Collective ownership</em></strong> could shift to <strong><em>Weak code ownership</em></strong> where developers could take additional responsibility for the modules they implemented and keep an eye on changes made by other developers, additional responsibility is fine and every developers could have some fillings to code which they produce and be more interesting in evolution of it into right direction but there need to be a balance and such additional responsibility should not become a protection from other developers changes which could lead to <strong><em>Strong code ownership</em></strong>.</p><p>Also there could be opposite case where team put additional responsibility on author of changes and it could happens where some PRs are accepted with rush due deadlines or accepted by someone who is not fully responsible for collective ownership or PR changes was so big that it wasn’t possible review it in precise way but it was accepted by some reasons. In such cases, a team could disassociate from such code and put additional responsibility on the author of it since it was not properly accepted and the team doesn’t want to take responsibility for it. This situation could be solved by them-self during some time as team go through such implementation and improve/refactor it, and it is good point if author has responsibility about own code and put additional efforts to fix/improve it and bring it back to <strong><em>Collective ownership</em></strong> as fast as possible, but there is a chance that such developer could avoid such responsibility and maybe even forgot about some promises, when team will highlight the problem there could be excuses that it’s <strong><em>Collective ownership</em></strong> and responsibility, by the time it’s not even a <strong><em>Weak code ownership</em></strong> it shifts directly to <strong><em>Strong ownership</em></strong> simply because no one wants to be involved into areas of code which own author avoid, so better when developer has additional responsibility then has no it at all, and it is more critical in cases when review process wants to be better.</p><p>Few points to highlight about review process which I think could make sense:</p><p>1— keep PR small so they could easily pass review process and every one of the team developer could understand changes without diving into details, so setup limits on changes in single PR and do not accept large PR’s with excuses like “it’s not so big”, “we need merge it at once due dependencies” etc.</p><p>2 — PR could be merged only after everything is done, no unresolved comments, because after it’s merged there will be no more authors responsibility for it, so do not accept excuses like: “no time for polishing, it expects to be done yesterday”, “it will be updated later”. I think there could be single exception to perform some work later if it’s not closely related to PR and could increase complexity and size of it, but it needs to be described and linked to the source of the issue before PR will be merged</p><p>3 — reviewer is more responsible for accepted code then author because he represent <strong><em>Collective</em> <em>ownership</em></strong>, so if there will be question about quality they will be directed to reviewer in first place and it could be possible that after few such questions reviewer cannot be able to make acceptance decisions by them-self, at same time it’s better when acceptance of PR is based on couple of reviewers decision</p><p>4 — reviewer as developer need to understand that after merge he could be next who will work with that code, so make sure that it will be a pleasure to continue work with it and it’s one more reason why reviewer need to be involved into code crafting</p><p><a href="https://martinfowler.com/bliki/CodeOwnership.html">Martin Fowler — Code Ownership</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dff180744c0a" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>