我的目的是为我的Rails应用程序在各个地方创建自定义错误类,因为大多数错误类都有相同的方法。我决定创建一个YAML文件来包含来自各种错误类的所有信息,并使用类工厂脚本在运行时生成所有类。这就是我所拥有的:
chat_policy.rb
class ChatPolicy; ... end
class ChatPolicy::Error < StandardError
ERROR_CLASSES = GLOBAL_ERROR_CLASSES['chat_policy']
ERROR_CLASSES.each do |cls|
const_set(cls['class_name'], Class.new(ChatPolicy::Error) {
attr_reader :object
def initialize(object)
@object = object
end
define_method(:message) do
cls['message']
end
define_method(:code) do
cls['code']
end
})
end
从YAML.load加载GLOBAL_ERROR_CLASSES
并转向对象。
error_classes.yml
chat_policy:
- class_name: UserBlacklisted
message: You are not allowed to do this
code: ECP01
- class_name: UserSuspended
message: You are not allowed to do this
code: ECP02
- class_name: UserNotEligibleToRent
message: You are not allowed to do this
code: ECP03
- class_name: MembershipTierNotAllowed
message: You are not allowed to do this
code: ECP04
* __问题是__ *
现在我有其他文件,例如register_policy
,checkout_policy
,discount_policy
..等。如果我必须在每个策略文件中进行类生成,那将是非常重复的。我想知道我是否可以将代码缩短为:
chat_policy_intended.rb
class ChatPolicy::Error < StandardError
ERROR_CLASSES = GLOBAL_ERROR_CLASSES['chat_policy']
error_class_factory(ChatPolicy::Error, ERROR_CLASSES)
end
discount_policy_intended.rb
class DiscountPolicy::Error < StandardError
ERROR_CLASSES = GLOBAL_ERROR_CLASSES['discount_policy']
error_class_factory(DiscountPolicy::Error, ERROR_CLASSES)
end
error_clas_factory.rb
ERROR_CLASSES.each do |cls|
const_set(cls['class_name'], Class.new(/*class_variable*/) {
attr_reader :object
def initialize(object)
@object = object
end
define_method(:message) do
cls['message']
end
define_method(:code) do
cls['code']
end
})
end
我尝试了什么
我试图创建一个基本上复制类工厂脚本的.rb文件。并使用eval
方法在运行时评估它,但似乎我可以将变量传入脚本
eval File.read(File.join(Rails.root, 'lib', 'evals', 'error_class_generator.rb'))
我该怎么办?
答案 0 :(得分:0)
我感谢您不惜一切代价避免重复自己的努力,但我发现您的代码对于您尝试解决的问题非常复杂,即向您的应用用户发送错误。
如何坚持更简单的< MyAppError
继承层次结构以避免重复的代码?
class MyAppError < StandardError
attr_reader :object
def message(message)
# does stuff
end
def code(code)
# also does stuff
end
end
class ChatPolicyError < MyAppError
def message(message)
'[CHAT POLICY]' + super
end
end
class UserBlacklisted < ChatPolicyError
def message(message)
# Does stuff too
super
end
end
[...] # You get the idea