尝试使用设计执行RemoteAuthetication,我遇到了一个例子(几乎是官方的一个,因为设计wiki仅限于引用this document)。
实际实现身份验证算法的所有类都是" double"包含在Devise,Models或Devise,Strategies中。
这是Devise,Models示例:
module Devise
module Models
module RemoteAuthenticatable
extend ActiveSupport::Concern
def remote_authentication(authentication_hash)
# Your logic to authenticate with the external webservice
end
end
end
end
第一个问题:你如何解释一个红宝石新手(就像我一样),也许来自另一种语言,比如java,这种命名空间的基本原理是什么?
虽然不同风格的命名空间在编程语言中很常见,但这种使用它们的特殊方式对我来说有点新鲜。
在其他语言中,即使在实现接口或扩展由它提供的类时,也不会使用第三方库的相同命名空间(例如在这种情况下设计)。
但是在这里我们看到设计本身,它的位,定义了
module Devise
module Models
module Authenticatable
extend ActiveSupport::Concern
...
end
end
第二个问题:这里的模块Authenticatable似乎扩展了另一个模块。我发现了很多关于类的文档,包括或扩展了其他模块,但没有扩展其他模块的模块。这是什么目的?
答案 0 :(得分:2)
如果查看对象模型,Ruby模块会附加到类中的祖先链中。所以:
Module B; end
class A
include B
end
A.ancestors # => A, B, etc.
现在当B扩展另一个模块时:
Module C
def a_module_method; end
end
Module B; extend C; end
然后Ruby将a_module_method
添加到祖先链中的类方法中。所以你可以这样做:
A.a_module_method
因此,这是一种让您访问模块方法的不同方法。一个很好的理由是将实例方法与类方法隔离开来。
答案 1 :(得分:2)
回复:问题1
命名空间提供组织。 Devise由几个集成到您的应用程序中的部分组成,例如。模型,控制器,验证逻辑等......
使用相同命名空间的原因可以是
但是,在重新打开您不拥有的课程/模块时,您确实要小心。
回复:问题2
模块与Class非常相似( Class实际上是Module的子代,然后它上传到Object然后是BasicObject ),除了它们不能实例。但是,他们可以拥有方法,变量和所有爵士乐,并充当一个单一的对象。因此,模块可以自然地包含和扩展其他模块,以获得在包含或扩展的模块中使用的逻辑。