-
-
Save gshaw/4adbebcba6ac954636e9 to your computer and use it in GitHub Desktop.
Example of why to use nested modules vs compact class namespaces in Ruby.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Wheels | |
def diameter | |
"diameter" | |
end | |
end | |
class Autos::Car | |
include Wheels | |
end | |
puts Autos::Car.new.diameter | |
# Results in: cars.rb:7:in `<main>': uninitialized constant Autos (NameError) | |
module Vehicles | |
class Truck | |
include Wheels | |
end | |
end | |
puts Vehicles::Truck.new.diameter | |
# Results in: diameter |
The uninitialized constant Autos
error above occurs because the Autos
namespace is not defined in advance of the Autos::Car
class. It's a problem with the compact syntax, yes, but it's not what my tweet was whinging about.
The include Wheels
business was about scoping; have a look:
module Autos
module Wheels
def diameter
"diameter"
end
end
end
# ... later ...
class Autos::Car
include Wheels
# Kaboom: uninitialized constant Autos::Car::Wheels (NameError)
# Doesn't have the "Auto" module context.
end
module Autos
class Truck
include Wheels
# Is inside Autos, can find Autos::Wheel just fine.
end
end
(I found this gist via rubocop/rubocop#868 when I went to look up the semantics again. I swear I didn't go googling my name. 😅 )
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
As a result of posting a comment on the Rubocop cop issue:
rubocop/rubocop#868 (comment)
This was posted as a reply:
https://twitter.com/damncabbage/status/463535409415204864