Inheriting/sharing 代码跨两个 Ruby 模块
Inheriting/sharing code across two Ruby modules
这里是菜鸟,正在寻求帮助来解决这个问题。假设我有 module DoAThing
看起来像这样:
module DoAThing
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(::ClassAwesome::EXPORT_DEFAULTS)
end
end
end
然后我想添加一个模块来做完全相同的事情,除了在生成报告时,我想传递一个不同的常量,所以像这样:
module DoASlightDifferentThing
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(::ClassAwesome::DIFFERENT_EXPORT_DEFAULTS)
end
end
end
我怎样才能优雅地把它擦干?从字面上看,我需要做的就是传入一个不同的常量,即我想将 EXPORT_DEFAULTS
换成 DIFFERENT_EXPORT_DEFAULTS
这通常被称为“依赖注入”,互联网上有很多关于这个主题的文章。主要方法是在调用 #perform
方法时接受一个参数:
module DoManyDifferentThings
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform(report)
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(report)
end
end
end
并这样称呼它:
DoManyDifferentThings::ExportNames.perform(
::ClassAwesome::EXPORT_DEFAULTS
)
报告方法是否应该有一个预定义的签名,一个可能与 class 继承:
module DoManyDifferentThings
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(self.class.constant_get('REPORT'))
end
end
class ExportNames1 < ExportNames
REPORT = ::ClassAwesome::EXPORT_DEFAULTS_1
end
class ExportNames1 < ExportNames
REPORT = ::ClassAwesome::EXPORT_DEFAULTS_2
end
end
或者,作为替代方案,可以声明一种方法在后代中被覆盖:
module DoManyDifferentThings
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(report)
end
protected
def report
raise "DO NOT CALL ME DIRECTLY"
end
end
class ExportNames1 < ExportNames
def report
::ClassAwesome::EXPORT_DEFAULTS_1
end
end
class ExportNames2 < ExportNames
def report
::ClassAwesome::EXPORT_DEFAULTS_2
end
end
end
如果 类 的命名空间可以相同,那么我会通过重写这样的代码来清理代码
module DoAThing
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform(value)
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(value)
end
end
end
现在我会打电话给
DoAThing::ExportNames.new('your names').perform(::ClassAwesome::EXPORT_DEFAULTS)
DoAThing::ExportNames.new('your names').perform(::ClassAwesome::DIFFERENT_EXPORT_DEFAULTS)
您可以将此常量作为参数移动,也可以使用 ihneritance。
提供默认值作为参数
module DoAThing
class ExportNames
def initialize(names, limit = 1000, defaults = ::ClassAwesome::EXPORT_DEFAULTS)
@names = names
@limit = limit
@defaults = defaults
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(@defaults)
end
end
end
不是调用 DoASlightDifferentThing::ExportNames,而是调用:
DoAThing::ExportNames.perform_now(names, 1000, ::ClassAwesome::DIFFERENT_EXPORT_DEFAULTS)
知识
或者您可以使用 ihneritance,我们在其中添加一个将被覆盖的默认方法:
module DoAThing
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(defaults)
end
def defaults
::ClassAwesome::EXPORT_DEFAULTS
end
end
end
module DoASlightDifferentThing
class ExportNames < DoAThing::ExportNames
def defaults
::ClassAwesome::DIFFERENT_EXPORT_DEFAULTS
end
end
end
这里是菜鸟,正在寻求帮助来解决这个问题。假设我有 module DoAThing
看起来像这样:
module DoAThing
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(::ClassAwesome::EXPORT_DEFAULTS)
end
end
end
然后我想添加一个模块来做完全相同的事情,除了在生成报告时,我想传递一个不同的常量,所以像这样:
module DoASlightDifferentThing
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(::ClassAwesome::DIFFERENT_EXPORT_DEFAULTS)
end
end
end
我怎样才能优雅地把它擦干?从字面上看,我需要做的就是传入一个不同的常量,即我想将 EXPORT_DEFAULTS
换成 DIFFERENT_EXPORT_DEFAULTS
这通常被称为“依赖注入”,互联网上有很多关于这个主题的文章。主要方法是在调用 #perform
方法时接受一个参数:
module DoManyDifferentThings
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform(report)
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(report)
end
end
end
并这样称呼它:
DoManyDifferentThings::ExportNames.perform(
::ClassAwesome::EXPORT_DEFAULTS
)
报告方法是否应该有一个预定义的签名,一个可能与 class 继承:
module DoManyDifferentThings
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(self.class.constant_get('REPORT'))
end
end
class ExportNames1 < ExportNames
REPORT = ::ClassAwesome::EXPORT_DEFAULTS_1
end
class ExportNames1 < ExportNames
REPORT = ::ClassAwesome::EXPORT_DEFAULTS_2
end
end
或者,作为替代方案,可以声明一种方法在后代中被覆盖:
module DoManyDifferentThings
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(report)
end
protected
def report
raise "DO NOT CALL ME DIRECTLY"
end
end
class ExportNames1 < ExportNames
def report
::ClassAwesome::EXPORT_DEFAULTS_1
end
end
class ExportNames2 < ExportNames
def report
::ClassAwesome::EXPORT_DEFAULTS_2
end
end
end
如果 类 的命名空间可以相同,那么我会通过重写这样的代码来清理代码
module DoAThing
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform(value)
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(value)
end
end
end
现在我会打电话给
DoAThing::ExportNames.new('your names').perform(::ClassAwesome::EXPORT_DEFAULTS)
DoAThing::ExportNames.new('your names').perform(::ClassAwesome::DIFFERENT_EXPORT_DEFAULTS)
您可以将此常量作为参数移动,也可以使用 ihneritance。
提供默认值作为参数
module DoAThing
class ExportNames
def initialize(names, limit = 1000, defaults = ::ClassAwesome::EXPORT_DEFAULTS)
@names = names
@limit = limit
@defaults = defaults
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(@defaults)
end
end
end
不是调用 DoASlightDifferentThing::ExportNames,而是调用:
DoAThing::ExportNames.perform_now(names, 1000, ::ClassAwesome::DIFFERENT_EXPORT_DEFAULTS)
知识
或者您可以使用 ihneritance,我们在其中添加一个将被覆盖的默认方法:
module DoAThing
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(defaults)
end
def defaults
::ClassAwesome::EXPORT_DEFAULTS
end
end
end
module DoASlightDifferentThing
class ExportNames < DoAThing::ExportNames
def defaults
::ClassAwesome::DIFFERENT_EXPORT_DEFAULTS
end
end
end