{"id":14564,"date":"2016-09-09T10:00:15","date_gmt":"2016-09-09T07:00:15","guid":{"rendered":"https:\/\/www.webcodegeeks.com\/?p=14564"},"modified":"2016-09-08T17:30:05","modified_gmt":"2016-09-08T14:30:05","slug":"good-module-bad-module","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/","title":{"rendered":"Good Module, Bad Module"},"content":{"rendered":"<p>You already know how to use modules in Ruby, but are you abusing them? In this post, we\u2019ll take a look at different ways to program with modules and why they may or may not be a great idea.<\/p>\n<h2>Namespace<\/h2>\n<p>Modules give you an easy way to namespace the rest of your code. For example, when you generate a new gem:<\/p>\n<pre class=\" brush:php\">$ bundle gem foo_bar_fighters<\/pre>\n<p>You get a default file with a module in it:<\/p>\n<pre class=\" brush:php\">$ cat foo_bar_fighters\/lib\/foo_bar_fighters.rb\r\nrequire &quot;foo_bar_fighters\/version&quot;\r\n\r\nmodule FooBarFighters\r\n  # Your code goes here...\r\nend<\/pre>\n<p>Now if you make a new class, you can put it in this <code>FooBarFighters<\/code> namespace:<\/p>\n<pre class=\" brush:php\">module FooBarFighters\r\n  class Song\r\n  end\r\nend<\/pre>\n<p>Now if you end up using another gem with a <code>Song<\/code> class, you can distinguish between the two by using <code>FooBarFighters::Song.new<\/code>.<\/p>\n<p>Is this a good or a bad use of a module?<\/p>\n<p>Since it\u2019s auto generated by <a href=\"http:\/\/bundler.io\/\">Bundler<\/a>, you can bet that using a module as a namespace is a good idea. Modules used this way allow any gem or project to use any class name that they desire without risk of cross contamination.<\/p>\n<p>That being said, if you have a very common name, like <code>FooBarFighters::File<\/code>, be careful; it\u2019s not always clear if you\u2019ll get your <code>File<\/code> constant or Ruby\u2019s built-in constant. It\u2019s best practice to not duplicate core class names even if they\u2019re in a namespace. If you do have to, you can use the full constant <code>FooBarFighters::File<\/code> for your constant and <code>::File<\/code> (with the <code>::<\/code> in front) for Ruby\u2019s built-in constant.<\/p>\n<h2>Method Sharing<\/h2>\n<p>You can put methods into a module and then \u201cmix\u201d (<em>i.e.<\/em>, include) them into a class.<\/p>\n<pre class=\" brush:php\">module Quack\r\n  def say\r\n    puts &quot;quack&quot;\r\n  end\r\nend\r\n\r\nclass WaterFowl\r\n  include Quack\r\nend\r\n\r\nWaterFowl.new.say\r\n# =&gt; &quot;quack&quot;<\/pre>\n<p>Is this good or bad module use?<\/p>\n<p>This simple example is fine. However, there\u2019s no real reason for the module. It would be simpler and there would be less code if we put that method right inside of the <code>WaterFowl<\/code> class.<\/p>\n<pre class=\" brush:php\">class WaterFowl\r\n  def say\r\n    puts &quot;quack&quot;\r\n  end\r\nend\r\n\r\nWaterFowl.new.say\r\n# =&gt; &quot;quack&quot;<\/pre>\n<p>Since the module makes it more complicated, it\u2019s bad, right? Well, let\u2019s look at two separate examples from one of my projects: <a href=\"https:\/\/github.com\/schneems\/wicked\">Wicked<\/a>.<\/p>\n<h2>Sharing Behavior Through Modules<\/h2>\n<p><a href=\"https:\/\/github.com\/schneems\/wicked\">Wicked<\/a> is a gem for building \u201cstep by step\u201d wizard style controllers. It is a module, and you use use it by including it in your controller:<\/p>\n<pre class=\" brush:php\">class AfterSignupController &lt; ApplicationController\r\n  include Wicked::Wizard\r\n\r\n  # ...\r\nend<\/pre>\n<p>      <i> <\/p>\n<p>Note the namespace, yay!<\/p>\n<p>      <\/i> <\/p>\n<p>It makes sense for Wicked to contain methods that are mixed into a controller since it can be mixed into multiple controllers.<\/p>\n<p>More than just methods though, the <code>Wicked::Wizard<\/code> module contains a set of behaviors that we want to share. When a user clicks on a specific link, we want them to go to the next page in the wizard flow. This is a good use of sharing methods via a module. In this case, the interface is provided by the module.<\/p>\n<p>A benefit of this approach is that multiple interfaces can be layered on the same class. Originally, when I made Wicked, the interface was provided by a class that you had to inherit from.<\/p>\n<pre class=\" brush:php\">class AfterSignupController &lt; Wicked::WizardController\r\n  # ...\r\nend<\/pre>\n<p>This was not so great since it limits the ability to inherit from other custom classes (because Ruby only supports single inheritance). By putting our behavior in a module, we allow for a kind of multiple inheritance:<\/p>\n<pre class=\" brush:php\">class AfterSignupController\r\n  include Wicked::Wizard\r\n  include SetAdmin\r\n  include MailAfterSuccessfulCreate\r\n  include FooBarFighters::MyHero\r\n  # ...\r\nend<\/pre>\n<h2>Module Method Extraction<\/h2>\n<p>Another use of splitting out methods can be seen in the <a href=\"https:\/\/github.com\/rails\/sprockets\">Sprockets gem<\/a>, which I currently maintain. Sprockets split up lots of behavior into modules; here\u2019s a taste of a few of the modules:<\/p>\n<ul>\n<li>Sprockets::HTTPUtils<\/li>\n<li>Sprockets::Mime<\/li>\n<li>Sprockets::Server<\/li>\n<li>Sprockets::Resolve<\/li>\n<li>Sprockets::Loader<\/li>\n<li>Sprockets::Bower <\/li>\n<li>Sprockets::PathUtils<\/li>\n<li>Sprockets::PathDependencyUtils<\/li>\n<li>Sprockets::PathDigestUtils<\/li>\n<li>Sprockets::DigestUtils <\/li>\n<li>Sprockets::SourceMapUtils<\/li>\n<li>Sprockets::UriUtils<\/li>\n<\/ul>\n<p>Each of these modules eventually makes its way to the class <code>Sprockets::Environment<\/code>, which is wrapped by <code>Sprockets::CachedEnvironment<\/code>. When you instantiate the object, it has 105 different methods. People call classes like this \u201cGod objects\u201d since they seem to be all powerful. The <code>Sprockets::Environment<\/code> class definition in the source code is only 27 lines long without comments:<\/p>\n<pre class=\" brush:php\">module Sprockets\r\n  class Environment &lt; Base\r\n    def initialize(root = &quot;.&quot;)\r\n      initialize_configuration(Sprockets)\r\n      self.root = root\r\n      self.cache = Cache::MemoryStore.new\r\n      yield self if block_given?\r\n    end\r\n\r\n    def cached\r\n      CachedEnvironment.new(self)\r\n    end\r\n    alias_method :index, :cached\r\n\r\n    def find_asset(*args)\r\n      cached.find_asset(*args)\r\n    end\r\n\r\n    def find_all_linked_assets(*args, \u2588)\r\n      cached.find_all_linked_assets(*args, \u2588)\r\n    end\r\n\r\n    def load(*args)\r\n      cached.load(*args)\r\n    end\r\n  end\r\nend<\/pre>\n<p>This is bad. We only have five methods in this file. Where did the other 100 methods come from? Splitting out methods into modules just to mix them back into one God object doesn\u2019t reduce complexity; it makes it harder to reason about.<\/p>\n<p>I admit that at one point in time, \u201cconcerns\u201d \u2014 the practice of splitting out behavior for one class into many modules \u2014 was in vogue, and I too indulged in it. I even have a <a href=\"https:\/\/github.com\/schneems\/wicked\/tree\/master\/lib\/wicked\/controller\/concerns\">concerns folder in Wicked<\/a>. While it\u2019s fine to expose an interface of <code>Wicked::Wizard<\/code> via a module, the project (and docs) do not expect you to directly include these modules:<\/p>\n<ul>\n<li><code>Wicked::Controller::Concerns::Action<\/code><\/li>\n<li><code>Wicked::Controller::Concerns::Path<\/code> <\/li>\n<li><code>Wicked::Controller::Concerns::RenderRedirect<\/code><\/li>\n<li><code>Wicked::Controller::Concerns::Steps<\/code><\/li>\n<\/ul>\n<p>These are then all mixed into <code>Wicked::Wizard<\/code>. Splitting things up doesn\u2019t make things easier \u2014 it only means I can pretend that my files are small and that my main module doesn\u2019t introduce that many methods. Even though I wrote the code, I\u2019m constantly confused about which file holds what method. If anything, splitting out files in this way makes my job as a maintainer harder.<\/p>\n<p>I previously wrote about <a href=\"http:\/\/schneems.com\/post\/21380060358\/concerned-about-code-reuse\/\">reusing code with concerns<\/a> and <a href=\"http:\/\/schneems.com\/post\/22192005006\/legacy-concerns-in-rails\/\">legacy concerns in Rails<\/a>. If you haven\u2019t read them, don\u2019t. Extracting methods into a module to only turn around and <code>include<\/code> them is worse than pointless. It\u2019s actively damaging to the readability of your codebase.<\/p>\n<h2>Global Methods<\/h2>\n<p>When you put a method on a module directly (<em>i.e.<\/em>, using <code>def self<\/code> or <code>extend self<\/code>), then it becomes a global method. You can see this in <code>Sprockets::PathUtils.entries<\/code> method:<\/p>\n<pre class=\" brush:php\">module Sprockets\r\n  module PathUtils\r\n  # ...\r\n\r\n  def self.entries(path)\r\n    if File.directory?(path)\r\n      entries = Dir.entries(path, encoding: Encoding.default_internal)\r\n      entries.reject! { |entry|\r\n        entry.start_with?(&quot;.&quot;.freeze) ||\r\n          (entry.start_with?(&quot;#&quot;.freeze) &amp;&amp; entry.end_with?(&quot;#&quot;.freeze)) ||\r\n          entry.end_with?(&quot;~&quot;.freeze)\r\n      }\r\n      entries.sort!\r\n      entries\r\n    else\r\n      []\r\n    end\r\n  end\r\nend<\/pre>\n<p>      <i> <\/p>\n<p>Code changed slightly for clarity of example.<\/p>\n<p>      <\/i> <\/p>\n<p>This method finds all the files in a given directory and does not include any hidden files and returns a sorted array.<\/p>\n<p>You can use this method globally:<\/p>\n<pre class=\" brush:php\">Sprockets::PathUtils.entries(&quot;\/weezer\/blue-album&quot;)\r\n# =&gt; [&quot;Buddy Holly&quot;, &quot;Holiday&quot;, &quot;In the Garage&quot;, &quot;My Name Is Jonas No One Else&quot;, &quot;Only in Dreams&quot;, &quot;Say It Ain't So&quot;, &quot;Surf Wax America&quot;, &quot;The World Has Turned and Left Me Here&quot;, &quot;Undone \u2013 The Sweater Song&quot;]<\/pre>\n<p>The pros here are that the method can be used globally. This simple functionality can be tapped into by any piece of code without having to include the module. That means other code only has to know about the methods it needs instead of getting all the methods in the <code>PathUtils<\/code> module.<\/p>\n<p>The downside is that the method can be used globally; its scope isn\u2019t limited. If you need to change the behavior \u2014 let\u2019s say you need to return the array in reverse sorted order \u2014 you might break other code that you didn\u2019t even know was relying on this method.<\/p>\n<p>Is sharing methods globally by using methods directly on classes good or bad?<\/p>\n<p>Ideally you wouldn\u2019t need a global method, but sometimes it makes sense as an API. One example is <code>FileUtils<\/code>. I use this all the time to make directories:<\/p>\n<pre class=\" brush:php\">require 'fileutils'\r\n\r\nFileUtils.mkdir_p(&quot;\/ruby\/is\/awesome\/lets\/make\/directories&quot;)<\/pre>\n<p>This is a global method, and <code>FileUtils<\/code> is a module:<\/p>\n<pre class=\" brush:php\">puts FileUtils.class\r\n# =&gt; Module<\/pre>\n<p>I\u2019ll say that using modules for global methods is better than for building God objects. How so? If you look at the code:<\/p>\n<pre class=\" brush:php\">def stat_digest(path, stat)\r\n  if stat.directory?\r\n    # If its a directive, digest the list of filenames\r\n    digest_class.digest(\r\n      self.entries(path) # &lt;===================\r\n    .join(','.freeze))<\/pre>\n<p>I would prefer if it was more explicit:<\/p>\n<pre class=\" brush:php\">def stat_digest(path, stat)\r\n  if stat.directory?\r\n    # If its a directive, digest the list of filenames\r\n    digest_class.digest(\r\n      PathUtils.entries(path) # &lt;===================\r\n    .join(','.freeze))<\/pre>\n<p>In the second example, we know exactly where to look for our implementation (in the <code>PathUtils<\/code> module) since it\u2019s right in front of us. We also know that the method call isn\u2019t mutating anything that is not passed in. For example, <code>PathUtils<\/code> could be mutating the path argument but nothing else. It doesn\u2019t have access to any of the rest of the current scope.<\/p>\n<p>We still haven\u2019t said if sharing global methods via modules is good or bad. If there is no way you can work around needing a global method, what are other options for exposing a method globally?<\/p>\n<p>You could define it in a top level context:<\/p>\n<pre class=\" brush:php\">$ irb\r\n&gt; def nirvana\r\n    puts &quot;come as you are&quot;\r\n  end\r\n\r\n&gt; class Foo\r\n    def say\r\n      nirvana\r\n    end\r\n  end\r\n\r\n&gt;  Foo.new.say\r\n# =&gt; &quot;come as you are&quot;<\/pre>\n<p>You could also \u201cmonkey patch\u201d it into <code>Object<\/code> or <code>Kernel<\/code>:<\/p>\n<pre class=\" brush:php\">class Object\r\n  def nirvana\r\n    puts &quot;come as you are&quot;\r\n  end\r\nend\r\n\r\nclass Foo\r\n  def say\r\n    nirvana\r\n  end\r\nend\r\nFoo.new.say\r\n# =&gt; &quot;come as you are&quot;<\/pre>\n<p>We can agree (hopefully) that both of these approaches are more surprising and more invasive to the end user than stashing our global methods in a module. We\u2019ll say that using modules for global methods is \u201cgood.\u201d<\/p>\n<h2>Bad Modules Make for Good Objects<\/h2>\n<p>Many of the \u201cbad\u201d module practices (including my own) came from a somewhat limited understanding of object-oriented design.<\/p>\n<p>You may hear things like \u201cnever have a file longer than [some number] lines of code,\u201d which leads you to think that taking the existing methods, splitting them out into modules and including them is the quick fix. While it will give you shorter files, it also makes things worse. It kills readability and grepability.<\/p>\n<p>A well-written class can be a work of art, while most modules tend to be proverbial junk drawers. This isn\u2019t a post on OO design though, so I\u2019ll punt on that. If you want to know more, look up \u201crefactoring confreaks Ruby,\u201d and you\u2019ll find a ton of material. One notable book on the subject is <a href=\"http:\/\/www.poodr.com\/\"><em>Practical Object Oriented Design in Ruby<\/em><\/a> by <a href=\"https:\/\/twitter.com\/sandimetz\">Sandi Metz<\/a>.<\/p>\n<p>Modules are a valuable tool in your Ruby toolbox. But next time you reach for a module to solve a problem, ask yourself if it\u2019s a \u201cgood\u201d fit for the job.  <\/p>\n<div class=\"attribution\">\n<table>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"https:\/\/blog.codeship.com\/good-module-bad-module\/\">Good Module, Bad Module<\/a> from our <a href=\"http:\/\/www.webcodegeeks.com\/join-us\/wcg\/\">WCG partner<\/a> Florian Motlik at the <a href=\"http:\/\/blog.codeship.com\/\">Codeship Blog<\/a> blog.<\/td>\n<\/tr>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>You already know how to use modules in Ruby, but are you abusing them? In this post, we\u2019ll take a look at different ways to program with modules and why they may or may not be a great idea. Namespace Modules give you an easy way to namespace the rest of your code. For example, &hellip;<\/p>\n","protected":false},"author":81,"featured_media":4128,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21],"tags":[95],"class_list":["post-14564","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ruby","tag-rails"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Good Module, Bad Module - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"You already know how to use modules in Ruby, but are you abusing them? In this post, we\u2019ll take a look at different ways to program with modules and why\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Good Module, Bad Module - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"You already know how to use modules in Ruby, but are you abusing them? In this post, we\u2019ll take a look at different ways to program with modules and why\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/flomotlik\" \/>\n<meta property=\"article:published_time\" content=\"2016-09-09T07:00:15+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Florian Motlik\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@http:\/\/twitter.com\/flomotlik\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Florian Motlik\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/\"},\"author\":{\"name\":\"Florian Motlik\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/c2ce85ee77a6cb5f80143c1f88bb8d10\"},\"headline\":\"Good Module, Bad Module\",\"datePublished\":\"2016-09-09T07:00:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/\"},\"wordCount\":1435,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg\",\"keywords\":[\"Rails\"],\"articleSection\":[\"Ruby\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/\",\"name\":\"Good Module, Bad Module - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg\",\"datePublished\":\"2016-09-09T07:00:15+00:00\",\"description\":\"You already know how to use modules in Ruby, but are you abusing them? In this post, we\u2019ll take a look at different ways to program with modules and why\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Ruby\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/ruby\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Good Module, Bad Module\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/c2ce85ee77a6cb5f80143c1f88bb8d10\",\"name\":\"Florian Motlik\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d325d3a5660b2d2b2b433ebbe06cac2210d8d0e5083c7998b4ca07cc24d7cf3e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d325d3a5660b2d2b2b433ebbe06cac2210d8d0e5083c7998b4ca07cc24d7cf3e?s=96&d=mm&r=g\",\"caption\":\"Florian Motlik\"},\"sameAs\":[\"http:\/\/blog.codeship.com\/\",\"https:\/\/www.facebook.com\/flomotlik\",\"http:\/\/at.linkedin.com\/in\/florianmotlik\",\"https:\/\/x.com\/http:\/\/twitter.com\/flomotlik\"],\"url\":\"https:\/\/www.webcodegeeks.com\/author\/florian-motlik\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Good Module, Bad Module - Web Code Geeks - 2026","description":"You already know how to use modules in Ruby, but are you abusing them? In this post, we\u2019ll take a look at different ways to program with modules and why","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/","og_locale":"en_US","og_type":"article","og_title":"Good Module, Bad Module - Web Code Geeks - 2026","og_description":"You already know how to use modules in Ruby, but are you abusing them? In this post, we\u2019ll take a look at different ways to program with modules and why","og_url":"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_author":"https:\/\/www.facebook.com\/flomotlik","article_published_time":"2016-09-09T07:00:15+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg","type":"image\/jpeg"}],"author":"Florian Motlik","twitter_card":"summary_large_image","twitter_creator":"@http:\/\/twitter.com\/flomotlik","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Florian Motlik","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/"},"author":{"name":"Florian Motlik","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/c2ce85ee77a6cb5f80143c1f88bb8d10"},"headline":"Good Module, Bad Module","datePublished":"2016-09-09T07:00:15+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/"},"wordCount":1435,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg","keywords":["Rails"],"articleSection":["Ruby"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/","url":"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/","name":"Good Module, Bad Module - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg","datePublished":"2016-09-09T07:00:15+00:00","description":"You already know how to use modules in Ruby, but are you abusing them? In this post, we\u2019ll take a look at different ways to program with modules and why","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/ruby\/good-module-bad-module\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Ruby","item":"https:\/\/www.webcodegeeks.com\/category\/ruby\/"},{"@type":"ListItem","position":3,"name":"Good Module, Bad Module"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/c2ce85ee77a6cb5f80143c1f88bb8d10","name":"Florian Motlik","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d325d3a5660b2d2b2b433ebbe06cac2210d8d0e5083c7998b4ca07cc24d7cf3e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d325d3a5660b2d2b2b433ebbe06cac2210d8d0e5083c7998b4ca07cc24d7cf3e?s=96&d=mm&r=g","caption":"Florian Motlik"},"sameAs":["http:\/\/blog.codeship.com\/","https:\/\/www.facebook.com\/flomotlik","http:\/\/at.linkedin.com\/in\/florianmotlik","https:\/\/x.com\/http:\/\/twitter.com\/flomotlik"],"url":"https:\/\/www.webcodegeeks.com\/author\/florian-motlik\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/14564","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/81"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=14564"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/14564\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/4128"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=14564"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=14564"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=14564"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}