我有以下模块,其中包含1个变量,其中包含一个假设年份第一天的字符串,1个输出字符串的方法和另一个输出字符串的方法:
module Week
first_day = "Sunday"
def weeks_in_month
puts "There are 4 weeks in a month"
end
def weeks_in_year
puts "There are 52 weeks in a year"
end
end
我现在有一个班级,其唯一目的是打印出模块中的变量。(这仅用于测试目的)
class Decade
include Week
def firstday
puts Week::first_day
end
end
我现在实例化Decade并使用Decades对象访问模块中的方法。调用第一天方法时,我的程序遇到问题
z = Decade.new
z.weeks_in_month
z.weeks_in_year
z.firstday #Errors here
我得到的错误是:
undefined method `first_day' for Week:Module (NoMethodError)
我是Ruby的新手,我刚刚习惯了模块,所以任何帮助都会受到赞赏。
答案 0 :(得分:0)
编写模块时,约定是声明这样的常量:
module Week
FIRST_DAY = 'Sunday'
end
请注意,他们在ALL_CAPS
中。任何以大写字母开头的东西都被视为常数。该类的小写名称被视为局部变量。
一般来说,访问另一个模块的常量是一种不好的形式,它限制了你重构这些模块存储方式的能力。而是定义一个公共访问器方法:
module Week
def first_day
FIRST_DAY
end
end
现在你可以在外面打电话了:
Week.first_day
请注意,您还可以更改实施方式:
module Week
DAYS = %w[
Sunday
Monday
Tuesday
...
Saturday
]
def first_day
DAYS.first
end
extend self # Makes methods callable like Week.first_day
end
关于这一点的好处是first_day
方法完全相同,没有其他代码必须改变。这使得重构变得更加容易。想象一下,如果你必须追踪并将所有这些实例替换为Week::FIRST_DAY
。
此处还有其他一些注意事项。首先,只要您在include
上调用module
,就可以获得本地加载的方法和常量。第二件事是当你定义一个混合模块时,要小心你的名字以避免与目标类的潜在冲突。
由于您已将其混入,因此您不需要命名空间前缀,只需调用first_day
即可。