模块和从模块访问变量(Ruby语言)

模块和从模块访问变量(Ruby语言),ruby,variables,module,instantiation,Ruby,Variables,Module,Instantiation,我有以下模块,其中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 我现在有一个类,它的唯一目的是打印出模块中的变量。

我有以下模块,其中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
我现在有一个类,它的唯一目的是打印出模块中的变量。(这只是为了测试)

现在,我实例化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新手,刚刚习惯了模块,希望您能提供帮助。

编写模块时,惯例是声明如下常量:

module Week
  FIRST_DAY = 'Sunday'
end
请注意,它们位于
所有\u 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
这方面的好处是
第一天
方法做了完全相同的事情,没有其他代码需要更改。这大大简化了重构。想象一下,如果您必须跟踪并将所有这些实例替换为
Week::FIRST_DAY

这里还有一些事情需要注意。第一种情况是,任何时候在
模块上调用
include
,都会在本地加载方法和常量。第二件事是,在定义混合模块时,请小心使用名称,以避免与目标类发生潜在冲突


由于您已将其混合在一起,因此不需要名称空间前缀,只需在第一天调用
即可。

编写模块时,惯例是声明如下常量:

module Week
  FIRST_DAY = 'Sunday'
end
请注意,它们位于
所有\u 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
这方面的好处是
第一天
方法做了完全相同的事情,没有其他代码需要更改。这大大简化了重构。想象一下,如果您必须跟踪并将所有这些实例替换为
Week::FIRST_DAY

这里还有一些事情需要注意。第一种情况是,任何时候在
模块上调用
include
,都会在本地加载方法和常量。第二件事是,在定义混合模块时,请小心使用名称,以避免与目标类发生潜在冲突


既然你已经混合了它,你不需要名称空间前缀,只要在第一天调用
就可以了。

别忘了用
{}
按钮或四个缩进空格格式化代码。别忘了用
{}
按钮或四个缩进空格格式化代码。啊,我认为常量的大写字母只是一种约定,但我猜这是实际语法,因此它没有编译。我来自java背景,在类定义和构造函数之间定义一个值会自动被视为类变量,而不一定是局部变量,因此与Ruby混淆。谢谢你的输入。啊,我以为常量的大写字母只是一种约定,但我猜这是实际语法,因此它没有编译。我来自java背景,在类定义和构造函数之间定义一个值会自动被视为类变量,而不一定是局部变量,因此与Ruby混淆。谢谢你的意见。