Ruby 模块中常量的范围 [英] Scope of Constants in Ruby Modules
问题描述
我在 mixin 模块中的常量作用域有点问题.假设我有这样的事情
I'm having a little problem with constant scope in mixin modules. Let's say I have something like this
module Auth
USER_KEY = "user" unless defined? USER_KEY
def authorize
user_id = session[USER_KEY]
def
end
除非已经定义,否则 USER_KEY 常量应该默认为user".现在我可能会将它混合到几个地方,但在其中一个地方 USER_KEY 需要不同,所以我们可能会有这样的东西
The USER_KEY constant should default to "user" unless it's already defined. Now I might mix this into a couple of places, but in one of those places the USER_KEY needs to be different, so we might have something like this
class ApplicationController < ActionController::Base
USER_KEY = "my_user"
include Auth
def test_auth
authorize
end
end
我希望 USER_KEY 在授权中使用时为my_user",因为它已经定义,但它仍然是user",取自 USER_KEY 的模块定义.任何人都知道如何获得使用 USER_KEY 的类版本的授权?
I would expect that USER_KEY would be "my_user" when used in authorize, since it's already defined, but it's still "user", taken from the modules definition of USER_KEY. Anyone have any idea how to get authorize to use the classes version of USER_KEY?
推荐答案
您在 Auth
中声明(甚至有条件地)的 USER_KEY
在全球范围内称为 Auth::USER_KEY
.它不会混入"到包含模块中,尽管包含模块可以以非完全限定的方式引用键.
The USER_KEY
you declared (even conditionally) in Auth
is globally known as Auth::USER_KEY
. It doesn't get "mixed in" to including modules, though including modules can reference the key in a non-fully-qualified fashion.
如果您希望每个包含模块(例如 ApplicationController
)能够定义自己的 USER_KEY
,请尝试以下操作:
If you want each including module (e.g. ApplicationController
) to be able to define its own USER_KEY
, try this:
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
不过,如果您要解决所有这些麻烦,不妨将其设为类方法:
If you're going to go to all this trouble, though, you might as well just make it a class method:
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 模块中常量的范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!