将变量传递到Ruby中的动态生成的类
问题描述:
我想通过编写一个动态生成的类方法来干我的代码。将变量传递到Ruby中的动态生成的类
我想是有多个错误类和我有以下代码
红宝石
class ChatPolicy::Error < StandardError
ERROR_CLASSES = [
{ class_name: 'UserBlacklisted', message: 'Message 1' },
{ class_name: 'UserSuspended', message: 'Message 2' },
{ class_name: 'UserNotEligibleToRent', message: 'Message 3' },
{ class_name: 'MembershipTierNotAllowed', message: 'Message 4' }
]
ERROR_CLASSES.each do |cls|
Object.const_set(cls[:class_name], Class.new {
attr_reader :object
def initialize(object)
@object = object
@message = cls[:message]
end
})
end
end
然而,由于在Class.new {}
块,变量不能被通过。我不能初始化消息变量。我想知道如何才能做到这一点?
答
当您使用def
定义方法时,不能在方法定义中引用外部范围的局部变量,即initialize
方法中的cls
变量。
您可以指的是块内部的这种局部变量,您可以使用块创建一个方法define_method
。
所以在你的榜样,你可以得到它的工作通过改变线路
def initialize(object)
到
define_method(:initialize) do |object|
现在,因为该方法的身体是你可以参考cls
身体内部的块。
答
However, since in the
Class.new {}
block, the variable cannot be passed in.
这是不是“变量不能被通过,”这是关于“一个块中,接收器不同,cls
局部变量不能得到解决。”有实现目标两种可能的方法:
- 直接从什么是可见查找消息:
@message = ChatPolicy::Error::ERROR_CLASSES.detect do |hash|
hash[:class_name] == self.class.name
end[:message]
- 或使用class_eval
:
ERROR_CLASSES.each do |cls|
Object.const_set(cls[:class_name], class_eval %Q|
Class.new {
attr_reader :object
def initialize(object)
@object = object
@message = '#{cls[:message]}' # ⇐ HERE !!!
end
}|)
end
UPD @matt的方法更好;我只为了历史目的而留下这个答案。
+0
您和马特的解决方案都为您提供正确的解决方案。谢谢 –
谢谢@matt。它现在有效,但控制台发出警告。 '1:警告:顶级常量UserSuspended由ChatPolicy :: Error :: UserSuspended引用我想知道它是如何解决的? –
**更新**实际上它不起作用,因为当我在控制台中键入ChatPolicy :: Error :: UserSuspended时,它变成了'UserSuspended' –
基于@ mudasobwa的解决方案找到了解决方案。它不应该需要'Object.const_set'只使用'const_set' –