Ruby如何命名嵌套类的父类

时间:2016-12-21 17:41:53

标签: ruby namespaces ruby-2.0 pundit

在使用Ruby gem Pundit时,我意识到我不确定某些命名空间在Ruby中的工作方式,我不喜欢神秘/不确定性。

Pundit建议你设置一个application_policy.rb

class ApplicationPolicy
  class Scope
     .
     .
     .
  end
end

课堂内实际发生的事情并不重要,只是课程的结构。

然后为从ApplicationPolicy继承的特定资源指定策略,例如post_policy.rb

class PostPolicy < ApplicationPolicy
  class Scope < Scope
  end
end

我的一般问题是,在PostPolicy内,当我声明Scope < Scope时,父Scope提到了什么?它是否会在外部类的父级中自动命名?那么它与继承ApplicationPolicy::Scope基本相同吗?我无法找到自己回答这个问题的方法,谢谢!

2 个答案:

答案 0 :(得分:4)

很容易让自己:

class C1; class Nested; end; end
class C2<C1; class Nested<Nested; end; end

C2::Nested.ancestors
#⇒ [
#  [0] C2::Nested < C1::Nested,
#  [1] C1::Nested < Object,
#  [2] Object < BasicObject,
#  [3] PP::ObjectMixin,
#  [4] Kernel,
#  [5] BasicObject
# ]

所以,是的,它隐含地解决了ApplicationPolicy::Scope

答案 1 :(得分:4)

简短回答

你是对的。您可以使用Class#ancestors

进行检查
class ApplicationPolicy
  class Scope
  end
end

class PostPolicy < ApplicationPolicy
  class Scope < Scope
  end
end

p PostPolicy::Scope.ancestors
#=> [PostPolicy::Scope, ApplicationPolicy::Scope, Object, Kernel, BasicObject]

等效代码

以上代码与:

完全相同
class ApplicationPolicy
end

class ApplicationPolicy::Scope
end

class PostPolicy < ApplicationPolicy
end

class PostPolicy::Scope < ApplicationPolicy::Scope
end

p PostPolicy::Scope.ancestors
#=> [PostPolicy::Scope, ApplicationPolicy::Scope, Object, Kernel, BasicObject]

请注意,PostPolicy::Scope不会从PostPolicy继承。它们是独立的类,前者恰好在后者的命名空间中定义。

检查

的另一种方法
class A
  class Scope
  end
end

class B < A
  class Scope < Scope
  end
end

class C
  class Scope < Scope
  end
end

失败了:

namespace.rb:26:in `<class:C>': uninitialized constant C::Scope (NameError)
    from namespace.rb:25:in `<main>'

这意味着Scope必须来自A名称空间。