我正在构建一个插件,允许开发人员在类定义中使用简单声明向类添加各种功能(遵循正常的acts_as模式).
例如,使用插件的代码可能看起来像
class YourClass
consumes_my_plugin option1: :value1, specific_method_to_use: :your_method
end
Run Code Online (Sandbox Code Playgroud)
我的问题出现了,因为我想错误地检查为:specific_method_to_use参数提供的值是否作为方法存在,但通常组织和加载代码的方式,该方法尚不存在.
我的插件中的代码暂时看起来像这样:
module MyPlugin
extend ActiveSupport::Concern
module ClassMethods
def consumes_my_plugin(options = {})
raise ArgumentError.new("#{options[:specific_method_to_use]} is not defined") if options[:specific_method_to_use].present? && !self.respond_to?(options[:specific_method_to_use])
end
end
end
Run Code Online (Sandbox Code Playgroud)
这可行:
class YourClass
def your_method; true; end
consumes_my_plugin option1: :value1, specific_method_to_use: :your_method
end
Run Code Online (Sandbox Code Playgroud)
但这是大多数人编写代码的方式,它不会:
class YourClass
consumes_my_plugin option1: :value1, specific_method_to_use: :your_method
def your_method; true; end
end
Run Code Online (Sandbox Code Playgroud)
如何在YourClass加载时失败?我希望它出错,而不是在运行时使用NoMethodError.我可以推迟执行引发ArgumentError的行,直到加载整个类,或者做一些其他聪明的事情来实现吗?
class A
def self.inherited(child)
puts "XXX"
end
end
class B < A
puts "YYY"
end
Run Code Online (Sandbox Code Playgroud)
打印出来
XXX
YYY
Run Code Online (Sandbox Code Playgroud)
我更喜欢
YYY
XXX
Run Code Online (Sandbox Code Playgroud)
如果我能以某种方式得到它.