我做了一个实用程序模块,有一些简单的功能-我希望模块扩展自我,所以它不需要被示例化。我和一位同事讨论了在这些类型的模块中存储数据的各种方法,他提供的一个例子是这样的,使用示例变量:
module ExampleModule
extend self
@my_instance_variable = "Hello from module"
def do_thing
puts "**** #{@my_instance_variable}"
@my_instance_variable
end
end
这不是我们决定使用的方法,但我想更好地了解为什么它有效/最佳替代方案。所以,有几个问题:
为什么这样做?没有示例的模块方法如何访问示例变量?你能给我指出任何讨论这种行为的ruby文档/文章吗?
如果/当这是一个适当的模式的想法?(我不是一个粉丝,因为像这样的模块拥有示例变量似乎是违反直觉的)
这里应该使用类变量吗?我们的rubocop flags @@foo class variables as a code smell
1条答案
按热度按时间ih99xse11#
Ruby中的类和模块都可以有示例变量。这是因为它们分别是Class和Module的示例。如果使用
Module.new
方法而不是关键字,这一点会变得更加明显:上面的例子和你的代码之间唯一的真实的区别是你使用的是
extend self
--这使得do_thing
可以在模块上调用,而不仅仅是模块扩展的类。我不是一个超级粉丝,恕我直言,最好只使用
def self.method_name
显式定义方法,这对意图更清楚,可以通过静态分析来获取。如果/当这是一个适当的模式的想法?(我不是一个粉丝,因为像这样的模块拥有示例变量似乎是违反直觉的)
模块示例变量的一个非常常见的用法是the configuration pattern:
这里,一组gem特定的设置存储在
@configuration
中。然后在启动应用程序时加载的初始化器文件中设置此参数:这允许应用程序范围的设置,而不依赖于全局。
如果你是Ruby新手,模块/类示例变量可能会让你感到困惑,但请记住,在Ruby中,一切都是对象,示例变量不是类的定义属性。它们只是在词法上作用域为 * 某个对象的示例 * 的变量,该对象可以是模块、类或类的示例。
这里应该使用类变量吗?我们的Rubocop将@@foo类变量标记为代码气味
Ruby中的类变量有很多意想不到的行为,因此通常最好避免。例如,它们在一个类和它的所有子类之间共享。