Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>class variables can work strangely, and this use shows that off. What is the scope of <code>@@ammo</code>? <code>Ammunition</code> or does <code>Tank</code> have its own copy of it? It turns out that <code>@@ammo</code> is scoped by the module, and the classes that include it can simply access it.</p> <pre><code>module Ammunition def self.included(base) base.class_eval do puts "@@ammo was: #{defined?(@@ammo) ? @@ammo.join(',') : 'nil'}" @@ammo = ['bullets'] puts "@@ammo is now: #{@@ammo}" puts '---' end end def unload @@ammo end end class Tank include Ammunition @@ammo += ['shells'] end class Airplane include Ammunition @@ammo += ['missiles', 'photon_torpedoes'] end puts "Tank unloaded: #{Tank.new.unload.join(', ')}" puts "Airplane unloaded: #{Airplane.new.unload.join(', ')}" </code></pre> <p>This produces:</p> <pre><code>@@ammo was: nil @@ammo is now: bullets --- @@ammo was: bullets,shells @@ammo is now: bullets --- Tank unloaded: bullets, missiles, photon_torpedoes Airplane unloaded: bullets, missiles, photon_torpedoes </code></pre> <p>When <code>Tank</code> includes the module, it sets <code>@@ammo</code> from nil to an array with bullets in it. When <code>Airplane</code> includes the module, it overwrites the ammo value we just set.</p> <hr> <p><strong>Here is what you want to do</strong></p> <pre><code>module Ammunition def self.included(base) base.class_eval do include Ammunition::InstanceMethods extend Ammunition::ClassMethods @ammo = ['bullets'] end end module ClassMethods def ammo @ammo end end module InstanceMethods def unload self.class.ammo.join(',') end end end class Tank include Ammunition @ammo += ['shells'] end class Airplane include Ammunition @ammo += ['missiles', 'photon_torpedoes'] end puts "Tank unloaded: #{Tank.new.unload}" puts "Airplane unloaded: #{Airplane.new.unload}" </code></pre> <p>Classes can have instance variables, and their scope is easier to understand. And separating your module into instance and class methods allow you to provide functionality to both. This snippet generates the following output</p> <pre><code>Tank unloaded: bullets,shells Airplane unloaded: bullets,missiles,photon_torpedoes </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload