我在 mixin 模块中遇到常量作用域的小问题。假设我有这样的东西
module Auth
USER_KEY = "user" unless defined? USER_KEY
def authorize
user_id = session[USER_KEY]
def
end
除非已经定义,否则 USER_KEY 常量应默认为“user”。现在我可能会把它混合到几个地方,但在其中一个地方 USER_KEY 需要不同,所以我们可能有这样的东西
class ApplicationController < ActionController::Base
USER_KEY = "my_user"
include Auth
def test_auth
authorize
end
end
我希望 USER_KEY 在授权中使用时会是“my_user”,因为它已经定义,但它仍然是“用户”,取自 USER_KEY 的模块定义。有人知道如何获得使用 USER_KEY 类版本的授权吗?
最佳答案
您在 Auth
中声明(甚至有条件地)的 USER_KEY
全局称为 Auth::USER_KEY
。它不会“混入”包含模块,尽管包含模块可以以非完全限定的方式引用 key 。
如果您希望每个包含模块(例如 ApplicationController
)能够定义自己的 USER_KEY
,请尝试以下操作:
module Auth
DEFAULT_USER_KEY = 'user'
def self.included(base)
unless base.const_defined?(:USER_KEY)
base.const_set :USER_KEY, Auth::DEFAULT_USER_KEY
end
end
def authorize
user_id = session[self.class.const_get(:USER_KEY)]
end
end
class ApplicationController < ActionController::Base
USER_KEY = 'my_user'
include Auth
end
但是,如果您要解决所有这些麻烦,您不妨将它作为一个类方法:
module Auth
DEFAULT_USER_KEY = 'user'
def self.included(base)
base.extend Auth::ClassMethods
base.send :include, Auth::InstanceMethods
end
module ClassMethods
def user_key
Auth::DEFAULT_USER_KEY
end
end
module InstanceMethods
def authorize
user_id = session[self.class.user_key]
end
end
end
class ApplicationController < ActionController::Base
def self.user_key
'my_user'
end
end
或类级访问器:
module Auth
DEFAULT_USER_KEY = 'user'
def self.included(base)
base.send :attr_accessor :user_key unless base.respond_to?(:user_key=)
base.user_key ||= Auth::DEFAULT_USER_KEY
end
def authorize
user_id = session[self.class.user_key]
end
end
class ApplicationController < ActionController::Base
include Auth
self.user_key = 'my_user'
end
关于ruby-on-rails - Ruby 模块中常量的作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2687276/