I have the following Module which has 1 variable which contains a string for the first day of a hypothetical year, 1 method which outputs a string and another method which also outputs a string:
first_day = "Sunday"
puts "There are 4 weeks in a month"
puts "There are 52 weeks in a year"
z = Decade.new
z.firstday #Errors here
undefined method `first_day' for Week:Module (NoMethodError)
When writing a module the convention is to declare constants like this:
module Week FIRST_DAY = 'Sunday' end
Note that they're in
ALL_CAPS. Anything that begins with a capital letter is treated as a constant. Lower-case names of that sort are treated as local variables.
Generally it's bad form to access the constants of another module, it limits your ability to refactor how those are stored. Instead define a public accessor method:
module Week def first_day FIRST_DAY end end
Now you can call that externally:
Note you can also change how that's implemented:
module Week DAYS = %w[ Sunday Monday Tuesday ... Saturday ] def first_day DAYS.first end extend self # Makes methods callable like Week.first_day end
The nice thing about that is the
first_day method does exactly the same thing, no other code has to change. This makes refactoring significantly easier. Imagine if you had to track down and replace all those instances to
There's some other things to note here. The first is that any time you call
include on a
module then you get the methods and constants loaded in locally. The second thing is when you define a mix-in module, be careful with your names to avoid potential conflict with the target class.
Since you've mixed it in, you don't need the namespace prefix, just calling
first_day should do it.