<?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[RubyCademy - Medium]]></title>
        <description><![CDATA[Ruby Mastery: https://www.rubycademy.com?src=8 - Medium]]></description>
        <link>https://medium.com/rubycademy?source=rss----c452c2c2e2d8---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>RubyCademy - Medium</title>
            <link>https://medium.com/rubycademy?source=rss----c452c2c2e2d8---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Mon, 11 May 2026 09:50:00 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/rubycademy" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[My two cents on coding and LLMs]]></title>
            <link>https://medium.com/rubycademy/my-two-cents-on-coding-and-llms-2ae932c9f0d2?source=rss----c452c2c2e2d8---4</link>
            <guid isPermaLink="false">https://medium.com/p/2ae932c9f0d2</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[openai]]></category>
            <category><![CDATA[llm]]></category>
            <category><![CDATA[chatgpt]]></category>
            <category><![CDATA[ruby-on-rails]]></category>
            <dc:creator><![CDATA[mehdinpublic]]></dc:creator>
            <pubDate>Tue, 01 Apr 2025 10:35:57 GMT</pubDate>
            <atom:updated>2025-04-01T10:34:05.934Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*v7gZ5okmAavvMUwvC_Fwkw.png" /></figure><h4><strong>Why real expertise still matters when the tools get smarter</strong></h4><p>Large Language Models (LLMs) have rapidly taken the spotlight in the tech community. They can seem magical when you first encounter them.</p><p>I think of them as powerful code editors with autocomplete on steroids..</p><p>They’re fast, adaptable, and incredibly knowledgeable. Need help recalling a rarely used method? Struggling with boilerplate code or syntax? Chances are, an LLM can assist you almost instantly.</p><p>However, beneath this impressive capability lies an important reality.</p><p>Without solid expertise in your chosen programming language (especially a nuanced one like Ruby), an LLM is merely guessing.</p><p>This isn’t to say it guesses poorly, but there’s a stark difference between functioning code and elegant, maintainable, idiomatic code.</p><blockquote><strong>‟ A sable brush and a glass palette mean little without knowing light, color, and composition.</strong></blockquote><blockquote><strong>A sable brush and a precision Mahl stick mean little without knowing light, color, and composition. ˮ</strong></blockquote><p>To illustrate, imagine handing someone exquisite painting tools such as a sable-bristle brush, a precision Mahl stick, and an elegant glass palette.</p><p>Without a foundational understanding of artistic concepts like composition, color theory, or lighting, these professional tools won’t produce a masterpiece. Instead, the outcome will be uninspired at best.</p><p>Coding, particularly in the Ruby on Rails ecosystem, mirrors this scenario closely. Ruby is nuanced and idiomatic, steeped in carefully honed community standards. Rails, in turn, has well-established conventions, methodologies, and best practices drawn directly from real-world usage.</p><p>An LLM might produce functional Rails code snippets, but without deep insight into why certain patterns and idioms exist, the resulting code is often shaky or insecure. This fuels arguments among developers:</p><ul><li>Pro-LLM enthusiasts argue passionately that these models herald the end of traditional coding roles, automating away human error and inefficiency.</li><li>Traditional coders counter just as strongly that LLM-generated code lacks the depth and foresight required to build secure, stable applications. They worry that “AI-assisted coders” produce tools that are superficially functional yet fundamentally fragile.</li></ul><p>Here’s my perspective:</p><p><strong>As is often the case, the truth lies somewhere in the middle.</strong></p><p>When you combine your deep, human understanding of Ruby’s idioms, design patterns, and Rails conventions with the speed and breadth of an LLM, something truly powerful emerges. The result isn’t just functional code; it’s elegant, maintainable, secure, and performant.</p><p>In short, LLMs become powerful assistants, enhancing-not replacing-the developer’s craft.</p><p>And that’s when things genuinely get interesting.</p><p>Just my two cents. 🙏</p><p>If you’re on this path and Ruby is part of your journey, it’d be my honour to share what I’ve learned over the years: 👉 <a href="https://www.rubycademy.com">https://www.rubycademy.com</a></p><p>Voilà!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2ae932c9f0d2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/rubycademy/my-two-cents-on-coding-and-llms-2ae932c9f0d2">My two cents on coding and LLMs</a> was originally published in <a href="https://medium.com/rubycademy">RubyCademy</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Art of Ruby Scripting]]></title>
            <link>https://medium.com/rubycademy/the-art-of-ruby-scripting-d7f5a64cff9e?source=rss----c452c2c2e2d8---4</link>
            <guid isPermaLink="false">https://medium.com/p/d7f5a64cff9e</guid>
            <category><![CDATA[rails]]></category>
            <category><![CDATA[linux]]></category>
            <category><![CDATA[ruby-on-rails]]></category>
            <category><![CDATA[ruby]]></category>
            <dc:creator><![CDATA[mehdinpublic]]></dc:creator>
            <pubDate>Sun, 30 Mar 2025 18:59:28 GMT</pubDate>
            <atom:updated>2025-07-07T16:24:45.952Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*J4t5KtWXlQKESw6LEiWqmQ.jpeg" /></figure><h4>Forget Complicated Scripts, Ruby is Your Secret Weapon for Automation!</h4><p>Scripting doesn’t have to be a headache. Ruby is uniquely powerful at transforming tedious tasks into quick, elegant solutions. Let’s dive deep into two realistic, everyday scripting challenges to showcase just how clearly and succinctly Ruby handles complex tasks.</p><h3>CASE STUDY 001 — Compress Your Videos</h3><p>Imagine finding yourself with a folder filled with large MOV and MP4 video files and needing an efficient way to compress them all. Here’s how easily Ruby accomplishes this:</p><pre>video_files = Dir.glob(&quot;{*.mov,*.mp4}&quot;, base: &quot;videos&quot;)<br><br>Dir.chdir(&#39;videos&#39;)<br><br>video_files.each do |video_file|<br>  file = video_file.sub(/\.(mov|mp4)$/, &#39;_compressed.\1&#39;)<br>  <br>`ffmpeg -i #{video_file} -vcodec h264 -acodec mp3 #{file}`<br>end</pre><h3>Line-by-Line Explanation</h3><p>The first line uses Ruby’s built-in Dir.glob method to efficiently find and list all .mov and .mp4 video files inside the &quot;videos&quot; directory. The curly braces {*.mov,*.mp4} represent a concise pattern that matches all files ending with either .mov or .mp4.</p><p>Next, Dir.chdir(&#39;videos&#39;) changes the current working directory to the &quot;videos&quot; folder, ensuring the script can execute commands directly on the listed files.</p><p>The video_files.each loop iterates through each collected video file, allowing actions to be performed individually on each one.</p><p>Within the loop, video_file.sub(/\.(mov|mp4)$/, &#39;_compressed.\1&#39;) uses Ruby&#39;s powerful regular expression substitution to create a new filename for each video file. The original file extension (.mov or .mp4) is captured by the (mov|mp4) group and then reused (\1) in the new filename, prefixing the file extension with _compressed.</p><p>Finally, the command enclosed in backticks executes the external command-line tool ffmpeg to compress each video file using the specified codecs: h264 for video and mp3 for audio, writing the compressed output to the newly defined filename.</p><p>Ruby’s clarity, concise syntax, and expressive methods significantly enhance script readability, allowing developers to quickly understand and maintain their automation tasks with minimal effort.</p><h3>CASE STUDY 002 — Bulk Renaming and Organizing Your Photo Library</h3><p>Imagine having thousands of photos scattered in a directory, each with generic filenames like IMG_1234.JPG. You want to rename them based on the date stored in their EXIF metadata and neatly organize them into folders by year and month. Ruby handles this complex task elegantly:</p><pre>require &#39;bundler/inline&#39;<br><br>gemfile do<br>  source &#39;https://rubygems.org&#39;<br>  gem &#39;mini_exiftool&#39;<br>end<br><br>require &#39;mini_exiftool&#39;<br>require &#39;fileutils&#39;<br><br>photos = Dir.glob(&quot;photos/*.JPG&quot;)<br><br>photos.each do |photo|<br>  exif       = MiniExiftool.new(photo)<br>  date_taken = exif.date_time_original<br>  <br>  next unless date_taken<br>  <br>  year_month    = date_taken.strftime(&quot;%Y/%m&quot;)<br>  new_directory = &quot;organized_photos/#{year_month}&quot;<br>  <br>  FileUtils.mkdir_p(new_directory)<br>  <br>  new_filename = date_taken.strftime(&quot;%Y-%m-%d_%H-%M-%S.jpg&quot;)<br>  new_filepath = File.join(new_directory, new_filename)<br>  <br>  FileUtils.cp(photo, new_filepath)<br>endruby</pre><h3>Line-by-Line Explanation</h3><p>First, the bundler/inline method allows including the mini_exiftool gem directly in the script without needing a separate Gemfile.</p><p>The inline gemfile do block explicitly declares the required external gem (mini_exiftool) and sets the gem source.</p><p>The script then requires the necessary modules: mini_exiftool for EXIF data extraction and Ruby’s built-in fileutils for file operations.</p><p>photos = Dir.glob(&quot;photos/*.JPG&quot;) collects all .JPG photo files within the photos directory.</p><p>Within the loop, MiniExiftool.new(photo) creates an object to access the photo&#39;s EXIF metadata. date_time_original retrieves the original date and time the photo was taken.</p><p>The script uses next unless date_taken to skip files without EXIF date data, ensuring robust handling of incomplete data.</p><p>Using strftime, the script formats the date into a year/month structure (YYYY/MM) for the new directories.</p><p>FileUtils.mkdir_p(new_directory) creates the directory path (organized_photos/YYYY/MM) if it doesn&#39;t already exist.</p><p>The filename itself is formatted clearly as YYYY-MM-DD_HH-MM-SS.jpg.</p><p>Finally, FileUtils.cp(photo, new_filepath) copies the photo into the newly created directory with its new, meaningful filename.</p><p>Ruby turns this potentially complex and tedious manual task into a straightforward, maintainable script.</p><h3>Conclusion</h3><p>Forget complicated scripts in other languages. With Ruby, scripting becomes straightforward, powerful, and elegant.</p><p>Ready to simplify your scripting life?</p><p>Try Ruby. It’s fantastic and unbeatable.</p><p>Our first eBook:</p><p>🔗 <a href="https://gum.co/u/pjpkl7he">https://gum.co/u/pjpkl7he</a></p><p>Voilà!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d7f5a64cff9e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/rubycademy/the-art-of-ruby-scripting-d7f5a64cff9e">The Art of Ruby Scripting</a> was originally published in <a href="https://medium.com/rubycademy">RubyCademy</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How link_to + Turbo Prefetching Speeds Up Navigation]]></title>
            <link>https://medium.com/rubycademy/how-link-to-turbo-prefetching-speeds-up-navigation-471bf1c7eb4c?source=rss----c452c2c2e2d8---4</link>
            <guid isPermaLink="false">https://medium.com/p/471bf1c7eb4c</guid>
            <category><![CDATA[ruby]]></category>
            <category><![CDATA[hotwire-rails]]></category>
            <category><![CDATA[turbo]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[ruby-on-rails]]></category>
            <dc:creator><![CDATA[mehdinpublic]]></dc:creator>
            <pubDate>Wed, 26 Mar 2025 14:48:46 GMT</pubDate>
            <atom:updated>2025-03-26T14:42:46.690Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TyMu80OuuKLq6eaK6vgwiA.png" /></figure><h4><strong>A 500–800ms speed boost you didn’t know you had!</strong></h4><p>Modern web users are impatient — and who can blame them? We’ve all clicked a link, waited a second, and immediately questioned our life choices.</p><p>But what if we could make every link in your Rails app feel <strong>instant</strong> without adding a single spinner or loading bar?</p><p>Thanks to <strong>Turbo v8</strong>, we can. And the secret? <strong>Prefetching links on hover</strong>.</p><p>Let’s dive into what this means for you as a Rails developer using good old link_to, and how you can make the most of it — or disable it where needed.</p><p><strong>Turbo v8 Prefetching: What It Actually Does</strong></p><p>Turbo now <strong>prefetches pages in the background</strong> as soon as the user hovers over a link for more than 100ms. That means the content starts loading <em>before</em> they even click.</p><p>On average, this gives you a <strong>500–800ms head start</strong>. And your app feels blazing fast.</p><p><strong>Real-World Rails Example: A Learning Dashboard</strong></p><p>Let’s say you’re building a learning dashboard in Rails, where users can quickly jump between “Today’s Lesson,” “Progress,” and “Leaderboard.”</p><p>Here’s how you’d typically render those links:</p><pre>&lt;ul class=&quot;sidebar-nav&quot;&gt;<br>  &lt;li&gt;&lt;%= link_to &quot;Today&#39;s Lesson&quot;, todays_lesson_path %&gt;&lt;/li&gt;<br>  &lt;li&gt;&lt;%= link_to &quot;Progress&quot;, progress_path %&gt;&lt;/li&gt;<br>  &lt;li&gt;&lt;%= link_to &quot;Leaderboard&quot;, leaderboard_path %&gt;&lt;/li&gt;<br>&lt;/ul&gt;</pre><p>With Turbo v8 installed (included in Rails 7+ apps using Hotwire), each of these links will <strong>prefetch their destination page</strong> as soon as the user hovers.</p><p>No extra markup. No JavaScript needed.</p><p>So when the user finally clicks “Leaderboard,” it loads like lightning ⚡</p><p><strong>Why Does This Feel So Fast?</strong></p><p>Because most latency isn’t the page load — it’s the <strong>network roundtrip</strong>. Turbo removes that by starting the request early, while the user is still thinking.</p><p>This works especially well for:</p><p>• Sidebar or dashboard menus</p><p>• Article indexes</p><p>• Multi-step workflows (e.g., onboarding wizards)</p><p><strong>When You Don’t Want to Prefetch</strong></p><p>Some pages don’t benefit from this, or even suffer from it.</p><p>Say you have a link that triggers <strong>expensive database queries</strong> or a Data Export that takes a while to prepare... No point preloading it unless the user clicks.</p><p>Let’s imagine a <strong>Data Export</strong> page that takes a while to prepare.</p><p>You can disable prefetching for just that link:</p><pre>&lt;%= link_to &quot;Data Export&quot;, export_path, data: { turbo_prefetch: false } %&gt;</pre><p>Turbo will skip prefetching this one while keeping the rest of the app fast.</p><p><strong>Scoping: Enable and Disable in Sections</strong></p><p>Imagine this layout:</p><pre>&lt;div class=&quot;admin-dashboard&quot;&gt;<br>  &lt;aside data-turbo-prefetch=&quot;true&quot;&gt;<br>    &lt;%= link_to &quot;Overview&quot;, admin_overview_path %&gt;<br>    &lt;%= link_to &quot;Users&quot;, admin_users_path %&gt;<br>  &lt;/aside&gt;<br><br>  &lt;main data-turbo-prefetch=&quot;false&quot;&gt;<br>    &lt;%= link_to &quot;Heavy Report&quot;, analytics_report_path %&gt;<br>    &lt;%= link_to &quot;Export Logs&quot;, logs_path %&gt;<br>  &lt;/main&gt;<br>&lt;/div&gt;</pre><p>Here’s what happens:</p><p>• All links inside &lt;aside&gt; are prefetched.</p><p>• All links inside &lt;main&gt; are <strong>not</strong> prefetched.</p><p>This gives you precise control, letting fast, frequent links get the speed boost, while leaving heavier ones alone.</p><p><strong>Bonus: Disable Prefetching for Mobile Users or Slow Networks</strong></p><p>Want to be respectful to users with limited data?</p><p>You can disable prefetching dynamically using JavaScript:</p><pre>document.addEventListener(&quot;turbo:before-prefetch&quot;, (event) =&gt; {<br>  if (navigator.connection?.saveData || isSlowConnection()) {<br>    event.preventDefault()<br>  }<br>});<br><br>function isSlowConnection() {<br>  return [&quot;slow-2g&quot;, &quot;2g&quot;].includes(navigator.connection?.effectiveType)<br>}</pre><p>This ensures you’re not fetching pages the user may never click, especially on metered or slow connections.</p><p><strong>✅ TL;DR</strong></p><p>• Turbo v8 <strong>prefetches links on hover</strong>, giving you ~500ms of perceived speed boost</p><p>• Works automatically with Rails link_to</p><p>• Disable globally with &lt;meta name=＂turbo-prefetch＂ content=＂false＂&gt;</p><p>• Disable per-link or per-section with data: { turbo_prefetch: false }</p><p>• You can re-enable selectively inside disabled areas</p><p>• Use turbo:before-prefetch to cancel based on network conditions</p><p><strong>🧵 Final Thought</strong></p><p>Prefetching might sound like a small optimization — but it’s one of those <em>feel</em> improvements that makes your app seem much faster than it really is.</p><p>The best part? You don’t have to change your app.</p><p>You’re already writing link_to. Turbo just makes it smarter.</p><p>Want more modern Rails tricks like this?</p><p>Check out <a href="https://www.rubycademy.com">RubyCademy</a> where we turn everyday Ruby, Rails, and Hotwire into your superpower.</p><p>Voilà!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=471bf1c7eb4c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/rubycademy/how-link-to-turbo-prefetching-speeds-up-navigation-471bf1c7eb4c">How link_to + Turbo Prefetching Speeds Up Navigation</a> was originally published in <a href="https://medium.com/rubycademy">RubyCademy</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Don’t Overcomplicate Refactoring!]]></title>
            <link>https://medium.com/rubycademy/dont-overcomplicate-refactoring-25ac0b3cfdf6?source=rss----c452c2c2e2d8---4</link>
            <guid isPermaLink="false">https://medium.com/p/25ac0b3cfdf6</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[ruby]]></category>
            <category><![CDATA[refactoring]]></category>
            <category><![CDATA[ruby-on-rails]]></category>
            <category><![CDATA[web-development]]></category>
            <dc:creator><![CDATA[mehdinpublic]]></dc:creator>
            <pubDate>Wed, 09 Oct 2024 09:25:18 GMT</pubDate>
            <atom:updated>2024-10-08T15:19:44.482Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9GrJwUgehWsfjnjUyI74kQ.jpeg" /><figcaption>Refactoring in Ruby.</figcaption></figure><p>Every developer knows the feeling: you’ve inherited a codebase that’s seen too many cooks in the kitchen. The classes are bloated, methods are sprawling, and the thought of refactoring it all — making it better, and more efficient — feels both exciting and overwhelming.</p><p>So where do you start? How do you get through it without getting caught in the complexity trap?</p><h4>Complexity Is an Invitation to Simplify</h4><p>There’s a misconception that refactoring is only for “big-brain moments” — those times when you’re ready to throw all the old code away and build something elegant from scratch. But refactoring doesn’t need to be a complete rebuild. It doesn’t have to be daunting.</p><p>The goal of refactoring isn’t to make code perfect. It’s to make it <em>better</em>. A small improvement is still an improvement.</p><p>It could be as simple as:</p><ul><li>Renaming a method to better describe what it does.</li><li>Extracting a few lines of code into a clearly named helper function.</li><li>Moving a related chunk of code into its own object.</li></ul><p>These changes aren’t rocket science. But they matter — they reduce cognitive load for the next developer (or yourself in a few months). They build momentum, instill confidence, and make working with the code enjoyable again.</p><h4>Avoid the Overengineering Trap</h4><p>It’s easy to get carried away when refactoring. You start by extracting some logic into a method, and before you know it, you’re building a new class with multiple dependencies, a new inheritance tree, and mixins to “keep it clean.”</p><p>Refactoring isn’t about adding complexity. It’s about removing what’s unnecessary and improving readability. Often, the best refactor makes the code more direct — clearer, more explicit, and more focused.</p><p>If you’re like me, you’ve experienced this firsthand: the deeper you go into refactoring, the greater the temptation to do a full architectural overhaul. But the beauty of refactoring lies in the small, incremental changes that guide the code towards simplicity.</p><h4>Start Small and Build Confidence</h4><p>The trick is to begin with something tiny — a change that doesn’t require weeks of rewriting and testing. These small wins lead to bigger wins. Start with one method. Or refactor a flaky test. The key is to keep it simple and maintain momentum.</p><p>For example, if you have a method that’s doing three different things — parsing data, calculating a value, and saving it to the database — you don’t need to split it into an entire suite of classes. Instead, start by extracting each responsibility into a small, named helper function within the same class. Suddenly, the method reads like a story — easy to follow and understand.</p><h4>You Don’t Need Complexity to Prove Your Worth</h4><p>We’ve all heard that little voice telling us a complicated solution shows off our skills. But the truth is, clean code speaks louder than clever code. Anyone can create something convoluted that no one else can understand. The real skill is making code easy to read, easy to modify, and easy to maintain.</p><p>Next time you’re refactoring, challenge yourself to <em>simplify</em>. Find ways to make the code more approachable. Leave it in a better state than you found it — without turning it into a massive new refactor project.</p><h4>The Path Forward</h4><p>Refactoring doesn’t have to be complicated or overwhelming. It can be a rewarding process of simplifying step by step. If you want to explore a no-nonsense approach to refactoring — one that encourages improvement without over-complication — I’ve got just the thing for you.</p><p>Let’s not overcomplicate refactoring. Let’s make it a habit, not a headache.</p><p>If this resonates with you, check out our “<a href="https://www.rubycademy.com/courses/dont-overcomplicate-refactoring">Don’t Overcomplicate Refactoring!</a>” course and see how simple, effective changes can transform your code — and your workflow.</p><p>Voilà!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=25ac0b3cfdf6" width="1" height="1" alt=""><hr><p><a href="https://medium.com/rubycademy/dont-overcomplicate-refactoring-25ac0b3cfdf6">Don’t Overcomplicate Refactoring!</a> was originally published in <a href="https://medium.com/rubycademy">RubyCademy</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Mastering the unary ampersand operator (&object) as a block argument]]></title>
            <link>https://medium.com/rubycademy/mastering-the-unary-ampersand-operator-with-blocks-cb5a48aca175?source=rss----c452c2c2e2d8---4</link>
            <guid isPermaLink="false">https://medium.com/p/cb5a48aca175</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[computer-science]]></category>
            <category><![CDATA[ruby]]></category>
            <category><![CDATA[ruby-on-rails]]></category>
            <category><![CDATA[chatgpt]]></category>
            <dc:creator><![CDATA[mehdinpublic]]></dc:creator>
            <pubDate>Fri, 10 Feb 2023 13:16:27 GMT</pubDate>
            <atom:updated>2024-10-11T12:13:05.883Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MuAXmsC97XYIKn9PA3hG2w.png" /></figure><h4>A complete overview of blocks, block references, and procs.</h4><p>Feel free to have a look at <a href="https://medium.com/rubycademy/the-yield-keyword-603a850b8921"><strong>The yield Keyword in Ruby</strong></a> if you’re not familiar the yield keyword and block arguments.</p><h3>The Ampersand Colon (&amp;:) operator</h3><p>Ruby proposes a shorthand to call a method on a block argument</p><pre>[1, 2, 3].map(&amp;:to_f) # =&gt; [2.0, 4.0, 6.0]</pre><p>Is equivalent to</p><pre>[1, 2, 3].map { |x| x.to_f } # =&gt; [2.0, 4.0, 6.0]</pre><p>By passing &amp;:to_i to Enumerable#map, each element of the[1, 2, 3] array calls to_i.</p><p>It works just fine. It’s magic... So let’s reveal the magic trick! 😉</p><blockquote>This operator is also called <strong><em>Pretzel colon</em></strong> operator.<em> 🥨 ☕</em></blockquote><h3>Symbol#to_proc</h3><p>When &amp; prepends an argument during a method call, Ruby expects the object passed as an argument to respond to to_proc</p><pre>module InspectToProc<br>  def to_proc<br>    puts &quot;to_proc is called upon :#{self.to_s}&quot;<br>    <br>    super<br>  end<br>end<br><br>Symbol.prepend InspectToProc<br><br>method_name = :to_f<br><br>[1, 2, 3].map(&amp;method_name) # =&gt; [1.0, 2.0, 3.0]</pre><p>produces</p><pre>to_proc is called upon :to_f</pre><p>Symbol#to_proc is called when &amp;:to_f is passed as an argument of map — which is a method that expects a block.</p><p>Then within each iteration of map, this freshly created proc will be used as the method’s block.</p><p>So let’s re-implement <a href="https://ruby-doc.org/3.2.0/Symbol.html#method-i-to_proc">Symbol#to_proc</a> to illustrate the above explanation</p><pre>module InspectToProc<br>  def to_proc = lambda {|elem| elem.send(self)} # returns a proc that expects one argument (elem) and calls self (:to_s in this case) upon elem.<br>end<br><br>Symbol.prepend InspectToProc<br><br>[1, 2, 3].map(&amp;:to_s) # =&gt; [&quot;1&quot;, &quot;2&quot;, &quot;3&quot;]</pre><p>is equivalent to</p><pre>to_string = lambda { |x| x.to_s }<br><br>[1, 2, 3].map {|x| to_string.yield(x) } # =&gt; [&quot;1&quot;, &quot;2&quot;, &quot;3&quot;]</pre><p>to_string is a lambda proc that converts an object into a string.</p><p>Then we pass x as argument of to_string.yield (the proc acting as a block) — which calls to_s upon x.</p><h3>Method#to_proc</h3><p>Another class that natively responds to #to_proc is Method. An instance of Method is the object-oriented representation of a method.</p><p>Instances can only be generated through the method(method_id) shorthand</p><pre>Method.new(:puts) # ❌ =&gt; NoMethodError: undefined method `new&#39; for Method:Class<br>method(:puts)     # ✅ =&gt; #&lt;Method: Object(Kernel)#puts&gt;</pre><p>Let’s see how to use Method objects with the &amp; ampersand operator</p><pre>def double(x) = x * 2 # I 💚 the shorthand syntax for single line methods!<br><br>[1, 2, 3].map &amp;method(:double) # =&gt; [2, 4, 6]</pre><p>is equivalent to</p><pre>def double(x) = x * 2<br><br>[1, 2, 3].map { |x| double(x) } # =&gt; [2, 4, 6]</pre><p>Here x is passed as an argument of double (double(x)) while in the previous section, to_s was called upon x (x.to_s).</p><p>It’s also possible to refer to a method encapsulated in another class</p><pre>require &#39;date&#39;<br><br>datetimes = %w(<br>  2001-02-03T04:05:06+07:00<br>  2002-03-04T04:05:06+08:00<br>  2003-04-05T04:05:06+09:00<br>)<br><br>datetimes.map(&amp;DateTime.method(:strptime)) # =&gt; [#&lt;DateTime: 2001-02-03T04:05:06+07:00 ((2451943j,75906s,0n),+25200s,2299161j)&gt;,                                         #&lt;DateTime: 2002-03-04T04:05:06+08:00 ((2452337j,72306s,0n),+28800s,2299161j)&gt;, #&lt;DateTime: 2003-04-05T04:05:06+09:00 ((2452734j,68706s,0n),+32400s,2299161j)&gt;] </pre><p>is equivalent to</p><pre>require &#39;date&#39;<br><br>datetimes = %w(<br>  2001-02-03T04:05:06+07:00<br>  2002-03-04T04:05:06+08:00<br>  2003-04-05T04:05:06+09:00<br>)<br><br>datetimes.map do |datetime|<br>  DateTime.strptime(datetime)<br>end # =&gt; [#&lt;DateTime: 2001-02-03T04:05:06+07:00 ((2451943j,75906s,0n),+25200s,2299161j)&gt;,                                         #&lt;DateTime: 2002-03-04T04:05:06+08:00 ((2452337j,72306s,0n),+28800s,2299161j)&gt;, #&lt;DateTime: 2003-04-05T04:05:06+09:00 ((2452734j,68706s,0n),+32400s,2299161j)&gt;]</pre><p>DateTime.strptime is a helper provided by the date standard library to parse string representations of date and time.</p><p>DateTime.method(:strptime) returns the object-oriented representation of strptime scoped under the DateTime class.</p><p>So the &amp; ampersand operator uses this instance of Method like in the previous example.</p><h3>A concrete implementation: BaseBuilder.to_proc</h3><pre># Input: Content of a JSON or CSV file uploaded to SFTP server for instance.<br>raw_users = [{email: &#39;a@a.com&#39;}, {email: &#39;b@b.com&#39;}, {email: &#39;c@c.com&#39;}]<br><br><br># Let&#39;s assume User to be an ActiveRecord model<br>User = Struct.new(:email, keyword_init: true)<br><br><br># BaseBuilder: it defines the Builder interface<br>class BaseBuilder<br>  attr :params<br><br>  def initialize(user_params) = @params = user_params<br>  <br>  # Emulated interface<br>  def build = raise(NotImplementedError)<br><br>  # Define to_proc at a class level<br>  def self.to_proc = proc { |user_params| new(user_params).build }<br>end<br><br><br># UserBuilder<br>class UserBuilder &lt; BaseBuilder<br>  def build = User.new(params)<br>end<br><br><br>raw_users.map &amp;UserBuilder # =&gt; [#&lt;struct User email=&quot;a@a.com&quot;&gt;, #&lt;struct User email=&quot;b@b.com&quot;&gt;, #&lt;struct User email=&quot;c@c.com&quot;&gt;]</pre><p>So let’s detail what happens in the above code snippet.</p><p>Here we define BaseBuilder which is a basic implementation of the Builder design pattern:</p><ul><li>it inits params (Each line of raw_users)</li><li>it emulates an interface contract with the build method.</li><li>it defines to_proc at a class level. this method returns a proc that instantiates a new builder and calls the build instance method on it.</li></ul><p>Then we define UserBuilder which derivates from BaseBuilder. So in order to be able to pass this class as a block reference to map, we must comply with the interface contract defined by BaseBuilder.</p><p>This means that we must define UserBuilder#build. If not, BaseBuilder#build is called and NotImplementedError is then raised.</p><p>As BaseBuilder.to_proc returns a proc and UserBuilder inherits from BaseBuilder then a call to raw_users.map &amp;UserBuilder calls BaseBuilder.to_proc.</p><p>So to define another enumerable builder, you just have to follow 2 rules:</p><ul><li>Make sure that your builder inherits from BaseBuilder</li><li>Define the #build method</li></ul><p>Cool! Isn’t it? 😁</p><p>Now to finish, let’s have a look at a particular use case where to_proc is not called when using block reference (&amp;object) as an argument.</p><h3>When to_proc is not called</h3><p>When &amp; prepends an argument during a method call, Ruby expects the object passed as an argument to respond to to_proc.</p><p>But this is not always the case</p><pre>module InspectToProc<br>  def to_proc<br>    puts &quot;to_proc is called upon :#{self.to_s}&quot;<br>    <br>    super<br>  end<br>end</pre><pre>Proc.prepend InspectToProc<br><br>double = proc {|x| x * 2}<br><br>[1, 2, 3].map(&amp;double) # =&gt; [2, 4, 6]</pre><p>Here InspectToProc#to_proc is never called as double is already an instance of Proc.</p><h3>Conclusion</h3><p>The Ampersand operator + Block pattern is widely used within the Ruby Standard Library and within multiple well-known gems (devise, etc..).</p><p>We all know this pattern through the famous Ampersand Colon operator (&amp;:).</p><p>But with a bit more knowledge, you are now able to extend the possibility of your Ruby code to another level!</p><h4>RubyCademy’s Newsletter</h4><p>In the RubyCademy newsletter, I share what I’m learning about Ruby &amp; Rails, including helpful tips, code insights, and exclusive Ruby Cards with detailed explanations.</p><p>If it sounds helpful, feel free to subscribe for <strong>free</strong>:</p><figure><a href="https://newsletter.rubycademy.com/subscribe"><img alt="" src="https://cdn-images-1.medium.com/max/213/1*o2zUxKA1MxKgafjomBFS-g.png" /></a></figure><blockquote>Thank you for taking the time to read this message!</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cb5a48aca175" width="1" height="1" alt=""><hr><p><a href="https://medium.com/rubycademy/mastering-the-unary-ampersand-operator-with-blocks-cb5a48aca175">Mastering the unary ampersand operator (&amp;object) as a block argument</a> was originally published in <a href="https://medium.com/rubycademy">RubyCademy</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[3 Must-Read Classic Books about Ruby and Ruby on Rails in 2021]]></title>
            <link>https://medium.com/rubycademy/3-must-read-classic-books-about-ruby-and-ruby-on-rails-in-2021-16042f288832?source=rss----c452c2c2e2d8---4</link>
            <guid isPermaLink="false">https://medium.com/p/16042f288832</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[ruby]]></category>
            <category><![CDATA[object-oriented]]></category>
            <category><![CDATA[ruby-on-rails]]></category>
            <category><![CDATA[web-development]]></category>
            <dc:creator><![CDATA[mehdinpublic]]></dc:creator>
            <pubDate>Fri, 01 Oct 2021 08:36:14 GMT</pubDate>
            <atom:updated>2023-09-04T18:09:46.716Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*pfc9Ldb243P1JJZQ" /><figcaption>Photo by <a href="https://unsplash.com/@madalyncox?utm_source=medium&amp;utm_medium=referral">Madalyn Cox</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h4>An exhaustive book list about Ruby and Ruby on Rails</h4><h3>Introduction</h3><p>We all want to become better programmers, and there is a tonne of books that’ll help you along your journey. In this blog, We’re going to list 3 Ruby and Ruby on Rails books that can have a big impact on your thought process as a Rubyist.</p><h3>Eloquent Ruby by Russ Olsen</h3><p>This book will help you to start writing code the “Ruby way”.</p><p>Indeed, it’s easy to write correct Ruby code but to gain the fluency needed to write great Ruby code, you must go beyond syntax and absorb the “Ruby way” of thinking and problem-solving. In Eloquent Ruby, Russ Olsen helps you write Ruby as true Rubyists do.</p><p>Here is a link to acquire this book:</p><p><a href="https://amzn.to/3oo3CyR">Eloquent Ruby (Addison-Wesley Professional Ruby Series)</a></p><h3>Practical Object-Oriented Design: An Agile Primer Using Ruby by Sandi Metz</h3><p>The book to learn to write long-term maintainable code for your Ruby and Ruby on Rails application.</p><p>Ruby’s widely admired simplicity has a downside: too many Ruby and Rails applications have been created without concern for their long-term maintenance or evolution. The Web is awash in Ruby code that is now virtually impossible to change or extend. This text helps you solve that problem by using powerful real-world object-oriented design techniques, thoroughly explained via simple and practical Ruby examples.</p><p>Here is a link to acquire this book:</p><p><a href="https://amzn.to/3ig0tNm">Practical Object-Oriented Design: An Agile Primer Using Ruby</a></p><h3>Agile Web Development With Rails 6</h3><p>Learn how to write Ruby on Rails applications the way the Rails core team recommends it.</p><p>If you’re new to Rails, you’ll get step-by-step guidance. If you’re an experienced developer, get the comprehensive, insider information you need for the latest version of Ruby on Rails. The new edition of this award-winning classic is completely updated for Rails 6 and Ruby 2.6+, with information on system testing, Webpack, and advanced JavaScript.</p><p>Here is a link to acquire this book:</p><p><a href="https://amzn.to/3AWH8bE">Agile Web Development with Rails 6</a></p><h3>Ruby Mastery</h3><p>We’re currently finalizing our first online course: <strong>Ruby Mastery</strong>.</p><p>Join the list for an exclusive release alert! 🔔</p><p>🔗 <a href="https://www.rubycademy.com/">Ruby Mastery by RubyCademy</a></p><p>Also, you can follow us on <a href="https://www.x.com/RubyCademy">x.com</a> as we’re very active on this platform. Indeed, we post elaborate code examples every day.</p><p>💚</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=16042f288832" width="1" height="1" alt=""><hr><p><a href="https://medium.com/rubycademy/3-must-read-classic-books-about-ruby-and-ruby-on-rails-in-2021-16042f288832">3 Must-Read Classic Books about Ruby and Ruby on Rails in 2021</a> was originally published in <a href="https://medium.com/rubycademy">RubyCademy</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Overriding private superclass methods in Ruby]]></title>
            <link>https://medium.com/rubycademy/overriding-private-superclass-methods-in-ruby-82ee4789c8f2?source=rss----c452c2c2e2d8---4</link>
            <guid isPermaLink="false">https://medium.com/p/82ee4789c8f2</guid>
            <category><![CDATA[ruby-on-rails]]></category>
            <category><![CDATA[oop]]></category>
            <category><![CDATA[ruby]]></category>
            <category><![CDATA[rails]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[mehdinpublic]]></dc:creator>
            <pubDate>Wed, 18 Nov 2020 15:06:51 GMT</pubDate>
            <atom:updated>2024-10-11T12:13:22.752Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*TjnlmxzSQNYnVeqB" /><figcaption>Photo by <a href="https://unsplash.com/@dtopkin1?utm_source=medium&amp;utm_medium=referral">Dayne Topkin</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h3>Overriding private methods of the superclass in Ruby</h3><h4>What happens when a private method of the superclass is overridden in Ruby?</h4><p>As Ruby is an OOP language, a class can inherit from another one. In Ruby, the inherited class is commonly referred to as <strong>superclass — </strong>This name comes from the <a href="https://ruby-doc.org/core-2.7.2/Class.html#method-i-superclass">Class#superclass</a> method that returns the directly inherited class of the receiver</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ff9369099769a5f8cade5e49c888225f/href">https://medium.com/media/ff9369099769a5f8cade5e49c888225f/href</a></iframe><p>Here, Parent defines the role method. Child that directly inherits from Parent, can call this method. This is due to the Method Lookup Path mechanism.</p><blockquote>Feel free to read the <a href="https://medium.com/rubycademy/ruby-object-model-part-1-4d06fa486bec"><strong><em>Ruby Object Model</em></strong> </a>article if you’re not familiar with this mechanism</blockquote><h3>Inheritance and private methods</h3><p>In Ruby, a private method is a method that can only be called with an implicit receiver — or with self as a receiver since <a href="https://www.ruby-lang.org/en/news/2019/12/25/ruby-2-7-0-released/">Ruby 2.7</a>.</p><p>In this area, the self refers to the eigenclass (a.k.a the shadow class.)</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bb0fd48b5f5bb8f36c6e11f8ee2ad7a2/href">https://medium.com/media/bb0fd48b5f5bb8f36c6e11f8ee2ad7a2/href</a></iframe><p>Here, the role private method is accessible in the inheriting Child class. So the state of an inherited method is kept through inheritance.</p><p>Now, what happens if we override the role private method?</p><h3>Overriding a private method</h3><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/70bd925971937366a3dd9c59b732f9d7/href">https://medium.com/media/70bd925971937366a3dd9c59b732f9d7/href</a></iframe><p>Here, Child class overrides Parent#role private method. In this case, we can see that role is defined as a public method after this overriding. Also, private_methods does not include #role even though this method is private in the ancestor chain of Child — through Parent#role method.</p><p>Indeed, private_methods knows that Child defines a role method. and as Child is the first entry of the ancestor chain (and the message handler during Method Lookup Path for a call to Child#role), it’ll be considered as the right version of #role to check by *_methods routines. So as Child#role isn’t defined as private, the private state of Parent#role isn’t inherited by Child#role.</p><h3>Conclusion</h3><p>So, always be careful when overriding methods defined with specific access control. Indeed, this state won’t be shared amongst the different versions of your method.</p><h4>RubyCademy’s Newsletter</h4><p>In the RubyCademy newsletter, I share what I’m learning about Ruby &amp; Rails, including helpful tips, code insights, and exclusive Ruby Cards with detailed explanations.</p><p>If it sounds helpful, feel free to subscribe for <strong>free</strong>:</p><figure><a href="https://newsletter.rubycademy.com/subscribe"><img alt="" src="https://cdn-images-1.medium.com/max/213/1*o2zUxKA1MxKgafjomBFS-g.png" /></a></figure><blockquote>Thank you for taking the time to read this message!</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=82ee4789c8f2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/rubycademy/overriding-private-superclass-methods-in-ruby-82ee4789c8f2">Overriding private superclass methods in Ruby</a> was originally published in <a href="https://medium.com/rubycademy">RubyCademy</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Arguments Forwarding shorthand in Ruby 2.7]]></title>
            <link>https://medium.com/rubycademy/the-arguments-forwarding-shorthand-in-ruby-2-7-af32d58c223b?source=rss----c452c2c2e2d8---4</link>
            <guid isPermaLink="false">https://medium.com/p/af32d58c223b</guid>
            <category><![CDATA[ruby-on-rails]]></category>
            <category><![CDATA[ruby]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[programming-languages]]></category>
            <category><![CDATA[rails]]></category>
            <dc:creator><![CDATA[mehdinpublic]]></dc:creator>
            <pubDate>Tue, 27 Oct 2020 07:19:05 GMT</pubDate>
            <atom:updated>2024-10-11T12:13:47.423Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*l_dH4e79UGicD44s" /><figcaption>Photo by <a href="https://unsplash.com/@jeffyactive?utm_source=medium&amp;utm_medium=referral">Jeffrey Dungen</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h4>How to 3-dots operator can be used to automatically forward arguments to another method call</h4><p>In Ruby, it occurs that a method directly forwards arguments to another one</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8bcfcc9c8f3a3791dbbaf1c56d497902/href">https://medium.com/media/8bcfcc9c8f3a3791dbbaf1c56d497902/href</a></iframe><p>Here, forwarding *args, **kwargs, &amp;blk is redundant and it impacts the readability of the code. To overcome this problem, Ruby 2.7 introduced the arguments forwarding shorthand</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e0b75604cc346aa7cf5227c4b1677636/href">https://medium.com/media/e0b75604cc346aa7cf5227c4b1677636/href</a></iframe><p>In the above example, everything passed to Exporter.run is forwarded to new. As new calls initialize then Exporter#initialize receives all the arguments passed to the call of Exporter.run.</p><p>Neat!</p><p>Now, what happens if Exporter.run needs to manipulate arguments to instantiate the right exporter, for example?</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6fed0e583086a96836d7de6c74cdc5c7/href">https://medium.com/media/6fed0e583086a96836d7de6c74cdc5c7/href</a></iframe><p>produces</p><pre>syntax error, unexpected def self.run(type, ...)<br>                                            ^^^</pre><p>Indeed, the arguments forwarding shorthand can’t be mixed with other arguments and it also can’t be destructured.</p><p>The above feature enhancement is in discussion since December 2019. So what if you still want to manipulate arguments before forwarding them to another method call?</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e71dfdde4fd10c98fd8bfaf063f58b06/href">https://medium.com/media/e71dfdde4fd10c98fd8bfaf063f58b06/href</a></iframe><blockquote>Feel free to have a look at the <a href="https://medium.com/rubycademy/is-module-function-really-the-same-as-extend-self-ac1e96a1cda0"><strong><em>module_function vs extend self</em></strong></a> article if you’re not familiar with the module_function method.</blockquote><p>In Exporter.run method, we declare a proc that takes 2 arguments:</p><ul><li>*_ : regular arguments (unused in the block)</li><li>**kwarg : keywords arguments</li></ul><p>In this block, we check if type passed as a keyword argument is whitelisted by Exporter. If so, we instantiate the right exporter by forwarding all the arguments using the Argument Forwarding shorthand—we instantiate Exporter::CSVExporter in this case.</p><p>Finally, we call the generate_export method on our freshly instantiated exporter.</p><p>The block passed to our proc can manipulate the arguments because the Argument Forwarding shorthand is passed to call. So the arguments passed to call are directly passed as arguments of the block.</p><h3>UPDATE: Ruby 3</h3><p>Arguments forwarding now supports leading arguments:</p><pre><strong>def</strong> <strong>method_missing</strong>(meth, <strong>...</strong>)<br>  send(:&quot;do_#{ meth }&quot;, <strong>...</strong>)<br><strong>end</strong></pre><h4>RubyCademy’s Newsletter</h4><p>In the RubyCademy newsletter, I share what I’m learning about Ruby &amp; Rails, including helpful tips, code insights, and exclusive Ruby Cards with detailed explanations.</p><p>If it sounds helpful, feel free to subscribe for <strong>free</strong>:</p><figure><a href="https://newsletter.rubycademy.com/subscribe"><img alt="" src="https://cdn-images-1.medium.com/max/213/1*o2zUxKA1MxKgafjomBFS-g.png" /></a></figure><blockquote>Thank you for taking the time to read this message!</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=af32d58c223b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/rubycademy/the-arguments-forwarding-shorthand-in-ruby-2-7-af32d58c223b">The Arguments Forwarding shorthand in Ruby 2.7</a> was originally published in <a href="https://medium.com/rubycademy">RubyCademy</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The defined? keyword in Ruby]]></title>
            <link>https://medium.com/rubycademy/the-defined-keyword-in-ruby-b7a5a5a48e1e?source=rss----c452c2c2e2d8---4</link>
            <guid isPermaLink="false">https://medium.com/p/b7a5a5a48e1e</guid>
            <category><![CDATA[ruby]]></category>
            <category><![CDATA[ruby-on-rails]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[rails]]></category>
            <dc:creator><![CDATA[mehdinpublic]]></dc:creator>
            <pubDate>Thu, 17 Sep 2020 06:39:54 GMT</pubDate>
            <atom:updated>2024-10-11T12:14:10.089Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DAwqXzLIU3rQINerqUBiLQ.jpeg" /><figcaption>Source: <a href="https://unsplash.com/photos/22zbwsn67ys">unsplash.com</a></figcaption></figure><h4>An overview of the defined? keyword with a use case from the Ruby source code.. and an optimization tip!</h4><p>In this article, we’re going to explore the following topics:</p><ul><li>the defined? keyword</li><li>defined? in the context of resolv-replace</li><li>defined? yield vs block_given?</li></ul><h3>The defined? keyword</h3><p>In Ruby, the defined? keyword returns a string that represents the type of entity passed as an argument. Here is an exhaustive list of what you can pass to defined?</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/78f16529038072adbd9339437d0fd29c/href">https://medium.com/media/78f16529038072adbd9339437d0fd29c/href</a></iframe><p>Here, we can see that defined? handles a maximum of cases. But some cases are more relevant than others. For example, let’s see how the resolv-replace library — available in the <a href="https://ruby-doc.org/stdlib-2.7.1/"><strong>Ruby Standard Library </strong></a>— takes advantage of this keyword to handle a really “tricky” case.</p><h3>defined? in the context of resolv-replace</h3><p>This library simply monkey-patches (IP|TCP|UDP|SOCKS)Socket classes provided by the socket library to use the Resolv <a href="https://ruby-doc.org/stdlib-2.7.1/libdoc/resolv/rdoc/Resolv.html">DNS resolver</a>.</p><p>In the case of SOCKSSocket, the monkey-patching only intervenes when the Ruby interpreter is compiled with the --enable-socks flag. So let’s see how the resolv-replace library handles this tricky case</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bd9d6b8ad29be98e04755b9af50564ad/href">https://medium.com/media/bd9d6b8ad29be98e04755b9af50564ad/href</a></iframe><p>Notice the modifier-if line 10. Indeed, to choose whether to monkey-patch this class or not, the resolv-replace library simply checks if the SOCKSSocket constant is defined using the defined? keyword. Indeed, as seen in the previous section, SOCKSSocket is only defined if the Ruby interpreter is compiled using the --enable-flag.</p><p>So, as the class keyword is only syntactic sugar for class definition and class opening, then you can call a modifier-if to execute this code (or not).</p><p>Now let’s see how using defined? can positively impact the performance of your application.</p><h3>defined?(yield) vs block_given?</h3><p>If in your program you deal with a huge amount of blocks, then defined? yield can definitely become a real optimization for your program performance. Indeed, to check if a block is passed to your method, you normally use the Kernel#block_given? method</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/dcc34f960676416a4e59778bc57c5fd6/href">https://medium.com/media/dcc34f960676416a4e59778bc57c5fd6/href</a></iframe><p>Here method_with_block_given checks if a block is passed as an argument by using Kernel#block_given?. If so, then yield is called and the block is executed. Otherwise, block_given? returns false and yield is never executed.</p><p>Ruby provides another way to achieve the same result: defined?(yield)</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1f45333753d140c5df25fe914f149f86/href">https://medium.com/media/1f45333753d140c5df25fe914f149f86/href</a></iframe><p>The main difference between these 2 expressions is that defined?(yield) is faster than Kernel#block_given?. Indeed, it’s a keyword when the block_given? is a method. So block_given? is slower because of the cost of the method call added to the cost of the <a href="https://www.rubycademy.com/screencasts/12#tabs">Method Lookup Path</a>.</p><p>Let’s generate <a href="https://github.com/evanphx/benchmark-ips">benchmark-ips</a> reports to see what’s the difference between defined?(yield) and block_given?</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/50c6084aac0cec639071a897248e4aba/href">https://medium.com/media/50c6084aac0cec639071a897248e4aba/href</a></iframe><p>We can see that block_given? is <strong>1.27x</strong> slower than defined?(yield).</p><p>But as seen in the above benchmark, we’re able to call block_given 9.897M times in a second. So keep in mind that this optimization is only relevant on a huge amount of block calls.</p><h3>Conclusion</h3><p>defined? isn’t the most popular keyword in Ruby. Nevertheless, in some situations, this keyword becomes a powerful asset to enhance your program performance or to handle tricky cases where a constant, method, etc... is conditionally loaded. Please feel free to share with us your experience with this keyword in the <strong>comments</strong> section.</p><h4>RubyCademy’s Newsletter</h4><p>In the RubyCademy newsletter, I share what I’m learning about Ruby &amp; Rails, including helpful tips, code insights, and exclusive Ruby Cards with detailed explanations.</p><p>If it sounds helpful, feel free to subscribe for <strong>free</strong>:</p><figure><a href="https://newsletter.rubycademy.com/subscribe"><img alt="" src="https://cdn-images-1.medium.com/max/213/1*o2zUxKA1MxKgafjomBFS-g.png" /></a></figure><blockquote>Thank you for taking the time to read this message!</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b7a5a5a48e1e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/rubycademy/the-defined-keyword-in-ruby-b7a5a5a48e1e">The defined? keyword in Ruby</a> was originally published in <a href="https://medium.com/rubycademy">RubyCademy</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[3 ways to make class methods private in Ruby]]></title>
            <link>https://medium.com/rubycademy/3-ways-to-make-class-methods-private-in-ruby-64b970e54613?source=rss----c452c2c2e2d8---4</link>
            <guid isPermaLink="false">https://medium.com/p/64b970e54613</guid>
            <category><![CDATA[object-oriented]]></category>
            <category><![CDATA[rails]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[ruby-on-rails]]></category>
            <category><![CDATA[ruby]]></category>
            <dc:creator><![CDATA[mehdinpublic]]></dc:creator>
            <pubDate>Mon, 14 Sep 2020 06:11:37 GMT</pubDate>
            <atom:updated>2024-10-11T12:14:22.944Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7mmWP1eONK28UenTW7lhrA.jpeg" /><figcaption>Source: <a href="https://unsplash.com/photos/HN3-ehlNwsc">unsplash.com</a></figcaption></figure><h4>An overview of the different ways to make class methods private in Ruby</h4><p>In this article we’re going to explore the following topics:</p><ul><li>private_class_method</li><li>class &lt;&lt; self and private</li></ul><h3>private_class_method</h3><p>This method takes one or more method_ids as an argument. A method_id can be either a String or a Symbol that represents an existing class method in the context of self. The private_class_method makes the method correspond to the method_id passed as argument <strong>private</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/eab9c8aa98d82c1bad763b274eaf1716/href">https://medium.com/media/eab9c8aa98d82c1bad763b274eaf1716/href</a></iframe><p>Here we can see that by passing :hello as argument of private_class_method the A::hello class method becomes private.</p><p>Now let’s see another way to make class methods private by also using private_class_method</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/179278d73c79ba7de35362a97da3457b/href">https://medium.com/media/179278d73c79ba7de35362a97da3457b/href</a></iframe><p>Here private_class_method takes the hello class method definition as an argument. Then we can see that our hello class method is private.</p><p>To understand what happens here, let’s slightly modify our code</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5a26e58194fbbd32bf38eb144c3b2b4b/href">https://medium.com/media/5a26e58194fbbd32bf38eb144c3b2b4b/href</a></iframe><p>Here we store the return value of the hello class method <strong>definition</strong> in method_id. Then we pass method_id (which contains :hello) to private_class_method. At this moment, the hello class method becomes private.</p><p>So as a method definition returns the method identifier, we can directly pass the method definition as an argument of private_class_method.</p><h3>class &lt;&lt; self and private</h3><p>The classic way to make class methods private is to open the eigenclass and use the private keyword on the instance methods of the eigenclass — which is what you commonly refer to as <strong>class methods</strong>.</p><blockquote>Feel free to have a quick look to my article <a href="https://medium.com/rubycademy/understanding-the-eigenclass-in-less-than-5-minutes-dcb8ca223eb4"><strong><em>about the eigenclass</em></strong></a> if you’re not familiar with this concept.</blockquote><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7963d4ef9cf0e124bf86b0266ed5428c/href">https://medium.com/media/7963d4ef9cf0e124bf86b0266ed5428c/href</a></iframe><p>Here, we simply open the eigenclass and make the hello class method private.</p><h4>RubyCademy’s Newsletter</h4><p>In the RubyCademy newsletter, I share what I’m learning about Ruby &amp; Rails, including helpful tips, code insights, and exclusive Ruby Cards with detailed explanations.</p><p>If it sounds helpful, feel free to subscribe for <strong>free</strong>:</p><figure><a href="https://newsletter.rubycademy.com/subscribe"><img alt="" src="https://cdn-images-1.medium.com/max/213/1*o2zUxKA1MxKgafjomBFS-g.png" /></a></figure><blockquote>Thank you for taking the time to read this message!</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=64b970e54613" width="1" height="1" alt=""><hr><p><a href="https://medium.com/rubycademy/3-ways-to-make-class-methods-private-in-ruby-64b970e54613">3 ways to make class methods private in Ruby</a> was originally published in <a href="https://medium.com/rubycademy">RubyCademy</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>