在对象的方法红宝石优先扩展为多个模块(Ruby precedence of methods in o

2019-09-28 09:09发布

考虑以下几点:

class User; attr_accessor :roles; end

module RegisteredUser
  def default_context
    Submission
  end
end

module Admin
  def default_context
    Review
  end
end

current_user = User.new
current_user.roles = ["registered_user", "admin"]
current_user.roles.each do |role|
  role_module = role.gsub(/ /, '_').camelize
  if module_exists?(role_module)
    current_user.extend role_module.constantize
  end
end
context = self.extend current_user.default_context

有没有一种方法来设置优先级User#default_context ? 也就是说,我可以说, Admin#default_context总是在优先RegisteredUser#default_context无论在哪个顺序的current_user延长?

Answer 1:

method_added是在Module

我其实是included ,不extended ,但两者也Module

该机制将围绕做这样的事情:

module Foo
  def self.included(base)
    base.extend(FooMethods)
  end

  module FooMethods
    def bar
      # Whatever
    end
  end
end

里面Foo.included可以判断,基于任意的标准,无论是否有问题的方法应该被添加到base (包括模块的实体)。

在你的情况,你可以检查,看看是否已经被列入了“优先级更高”模块,或者看看是否模块 “较高优先级”模块。 在此基础上,你会决定是否要添加的方法。



Answer 2:

由于管理员的也是RegisteredUser,我会做

module Admin
  include RegisteredUser
  ...
end

然后只

current_user.extend Admin

我不知道这是否是正确的方法。 如果管理员和RegisteredUser是类,它将使意义从RegisteredUser使管理员继承。 模块的情况下,不知道。



Answer 3:

你不能; 在红宝石模块夹杂物的次序是其中模块被搜索(顺序当前类后,父类之前 )。 改变“优先级”的唯一办法是包括在您想要的顺序的模块,或者将它们移动到一个父类。

虽然不是纯Ruby,你可以使用混音由banisterfiend库来改变模块的顺序(或unmixin模块,或者...其他的东西)。



文章来源: Ruby precedence of methods in objects extended with multiple modules
标签: ruby module dci