有关红宝石的信息:http://coderrr.wordpress.com/2008/03/11/constant-name-resolution-in-ruby/
不能帮助我解决我的问题..但它至少解释了他们'为什么'
我写了以下方法:
# delegate to a user permission serializer specific to the given object
# - if a serializer is not found for the given object, check the superclass
#
# @raise [NameError] if none of object, or it's superclasses have a known
# user permission serializer
# @return [UserPermission::*Serializer] returns serialized object
def self.serialized_for(object, user, klass: nil, recursion_limit: 5)
object_class = klass ? klass : object.class
# use demodulize to chop off the namespace and get the generic object name
object_name = object_class.name.demodulize
# bulid serializer name
name = "::UserPermission::#{object_name}Serializer"
begin
binding.pry
permissions = object.user_permissions(user)
return name.constantize.new(permissions)
rescue NameError => e
raise e if recursion_limit < 1
# try with super class
UserPermission.serialized_for(
object,
user,
klass: object_class.superclass,
recursion_limit: recursion_limit - 1
)
end
end
目标是能够检索任何子类的序列化程序,前提是子类具有已定义的序列化程序的超类。 (我正在使用ActiveModelSerializers,但这在这里并不重要。)
我的问题是我在name.constantize
运行时收到一个非命名空间的类。
我现有的课程:
我期待发生的事情是,当我使用UserPermission.serialized_for
致电Presentation
时,name.constantize
尝试给我一个::UserPermission::PresentationSerializer
,然后抛出一个NameError因为班级不存在。
我得到的是::PresentationSerializer
,这是不好的 - 用于不同的目的。
以下是我在irb
中复制问题的方法:
(也许上面的上下文对此有一个过于复杂的解释):
class NameSpace; end
class NameSpace::Klass; end
class Klass; end
class SubKlass < Klass; end
Object.const_get "::NameSpace::SubKlass"
=> SubKlass
Object.const_get("::NameSpace").const_get("SubKlass")
=> SubKlass
eval("NameSpace::SubKlass")
(eval):1: warning: toplevel constant SubKlass referenced by NameSpace::SubKlass
=> SubKlass
有没有办法可以对"::NameSpace::SubKlass"
进行限定,以便因NameSpace::SubKlass
不存在而导致NameError?
P.S。:我希望上下文有所帮助。
编辑:发现了另一个问题:
UserPermission::Template < UserPermission::Proposal
UserPermission::Template.superclass
=> Proposal
应为UserPermission::Proposal
UserPermission::Proposal
(pry):9: warning: toplevel constant Proposal referenced by UserPermission::Proposal
=> Proposal
UserPermission::Proposal
是一个班级。所以......这是一个大问题。 o.o
我正在使用Ruby 2.1.0
答案 0 :(得分:1)
不要以简洁的方式定义您的类和模块。你遇到了范围问题。
module UserPermission
class Proposal
end
end
module UserPermission
class Template < Proposal
end
end
UserPermission::Template.superclass
# => UserPermission::Proposal