{"id":570,"date":"2018-02-06T10:28:53","date_gmt":"2018-02-06T10:28:53","guid":{"rendered":"http:\/\/nicholshayes.co.uk\/blog\/?p=570"},"modified":"2018-02-06T13:51:38","modified_gmt":"2018-02-06T13:51:38","slug":"private-methods-in-ruby","status":"publish","type":"post","link":"http:\/\/nicholshayes.co.uk\/blog\/?p=570","title":{"rendered":"Private methods in Ruby"},"content":{"rendered":"<p>I think the way private methods are defined, is one of Ruby&#8217;s few weaknesses. The main problem being that they separate the private methods from the methods that use them. For example, I prefer this:<\/p>\n<div class=\"codecolorer-container ruby default\" style=\"overflow:auto;white-space:nowrap;height:300px;\"><div class=\"ruby codecolorer\"><span class=\"kw1\">def<\/span> one<br \/>\n&nbsp; internal_method<span class=\"br0\">&#40;<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"kw1\">end<\/span><br \/>\n<br \/>\n<span class=\"kw1\">def<\/span> two<br \/>\n&nbsp; internal_method<span class=\"br0\">&#40;<\/span><span class=\"nu0\">2<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"kw1\">end<\/span><br \/>\n<br \/>\n<span class=\"kw1\">def<\/span> internal_method<span class=\"br0\">&#40;<\/span>n<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; n<br \/>\n<span class=\"kw1\">end<\/span><br \/>\n<br \/>\n<span class=\"kw1\">def<\/span> three<br \/>\n&nbsp; other_internal_method<span class=\"br0\">&#40;<\/span><span class=\"nu0\">3<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"kw1\">end<\/span><br \/>\n<br \/>\n<span class=\"kw1\">def<\/span> four<br \/>\n&nbsp; other_internal_method<span class=\"br0\">&#40;<\/span><span class=\"nu0\">4<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"kw1\">end<\/span><br \/>\n<br \/>\n<span class=\"kw1\">def<\/span> other_internal_method<span class=\"br0\">&#40;<\/span>n<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; n<br \/>\n<span class=\"kw1\">end<\/span><\/div><\/div>\n<p>To:<\/p>\n<div class=\"codecolorer-container ruby default\" style=\"overflow:auto;white-space:nowrap;height:300px;\"><div class=\"ruby codecolorer\"><span class=\"kw1\">def<\/span> one<br \/>\n&nbsp; internal_method<span class=\"br0\">&#40;<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"kw1\">end<\/span><br \/>\n<br \/>\n<span class=\"kw1\">def<\/span> two<br \/>\n&nbsp; internal_method<span class=\"br0\">&#40;<\/span><span class=\"nu0\">2<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"kw1\">end<\/span><br \/>\n<br \/>\n<span class=\"kw1\">def<\/span> three<br \/>\n&nbsp; other_internal_method<span class=\"br0\">&#40;<\/span><span class=\"nu0\">3<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"kw1\">end<\/span><br \/>\n<br \/>\n<span class=\"kw1\">def<\/span> four<br \/>\n&nbsp; other_internal_method<span class=\"br0\">&#40;<\/span><span class=\"nu0\">4<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"kw1\">end<\/span><br \/>\n<br \/>\nprivate<br \/>\n<br \/>\n<span class=\"kw1\">def<\/span> internal_method<span class=\"br0\">&#40;<\/span>n<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; n<br \/>\n<span class=\"kw1\">end<\/span><br \/>\n<br \/>\n<span class=\"kw1\">def<\/span> other_internal_method<span class=\"br0\">&#40;<\/span>n<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; n<br \/>\n<span class=\"kw1\">end<\/span><\/div><\/div>\n<p>Because the former keeps the <em>internal_method<\/em> code close to the methods that use it.<\/p>\n<p>This issue is minimised if we keep classes small, but that&#8217;s not always as easy as it sounds.<\/p>\n<p>I&#8217;m also not particularly convinced about most arguments for making methods private. It takes a much more far sighted developer than me, to be sure that a method that I currently only use internally, won&#8217;t be useful externally later.<\/p>\n<p>I&#8217;d also be more convinced of the necessity to privatize methods if accessing private method was particularly hard, but it is not: <em>send(:private_method)<\/em><\/p>\n<p>It is also worth considering what is being written. If the code is part of a shared library (a gem for example), there is a more convincing argument for privatizing methods. However, if the Ruby code is written as part of a monolithic application (a Rails app for example), then I think the argument is far less convincing.<\/p>\n<p>Surely the only good reason for using a private method, is where the logic is only valid within the context of the current object, and using it outside that context is likely to result in errors. That is, external use will break things.<\/p>\n<p>For example where I do use private methods is in Rails controllers, where public methods could accidentally be exposed by a routing error causing security vulnerabilities and unexpected usage. If only the action methods are public, this vulnerability is greatly reduced.<\/p>\n<p>In summary, I&#8217;d say that a method should only be private if using it externally breaks something. If calling it externally doesn&#8217;t break anything, why restrict its use unnecessarily.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I think the way private methods are defined, is one of Ruby&#8217;s few weaknesses. The main problem being that they separate the private methods from the methods that use them. For example, I prefer this: def one &nbsp; internal_method&#40;1&#41; end &hellip; <a href=\"http:\/\/nicholshayes.co.uk\/blog\/?p=570\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/570"}],"collection":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=570"}],"version-history":[{"count":7,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/570\/revisions"}],"predecessor-version":[{"id":577,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/570\/revisions\/577"}],"wp:attachment":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=570"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=570"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=570"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}