Ruby 模块中常量的范围 [英] Scope of Constants in Ruby Modules

查看:22
本文介绍了Ruby 模块中常量的范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆