类内的命名空间方法

Namespace methods inside class

提问人:Brad 提问时间:4/29/2021 更新时间:4/30/2021 访问量:166

问:

我正在编写一个包装类以与 Clickup 的 API 集成,我想定义我的方法以匹配它们的 rest api 结构。所以我想,如果我可以对类内的方法进行命名空间,那就太酷了,例如:

class Clickup
    
    def initialize
        # sets some variables e.g. api token
    end

    module Users

        def get_all
            # make call to get all users
        end

    end

    module Lists

        def get_all
            # make call to get all lists
        end

    end
end

然后,我可以像这样编写代码:

clickup = Clickup.new

@users = clickup::users.get_all
@lists = clickup::lists.get_all

问题是我不知道这是否可行以及如何调用模块内的方法。

有没有人知道如何做到这一点,或者有更好的方法可以做到这一点?

理想情况下,我只想对 clickup 类进行一次设置,并且需要在类的根目录中设置变量才能被命名空间方法(例如 api 令牌)访问。

Ruby 命名空间

评论


答:

6赞 max pleaner 4/29/2021 #1

这实际上不可行。命名空间仅在类级别可用,而不在实例级别可用,因此可以工作但不能。你也许可以用一些元编程来做到这一点,但它会有点复杂,使你的代码更难理解。Clickup::UsersClickup.new::Users

不要错误地认为命名空间仅此而已 - 命名空间。仅仅因为 A::B 将 B 嵌套在 A 中,并不意味着它们之间存在任何关系。它们具有完全独立的状态和行为。

下面是一个有点类似的方法,可以工作,尽管它使你不得不重写几次。不过,这可能是一件好事。这意味着每个类都独立工作,并且只能传入所需的依赖项。initialize

请注意,我冒昧地将 4 空格缩进更改为 2,因为这是 Ruby 中的常态。

class Clickup   
  def initialize(config)
    @config = config
  end

  def users
    Users.new(@config)
  end

  def lists
    Lists.new(@config)
  end

  class Users
    def initialize(config)
      @config = config
    end

    def get_all
      # make call to get all users
    end
  end

  class Lists
    def initialize(config)
      @config = config
    end

    def get_all
      # make call to get all lists
    end
  end
end

用法将类似于您的想法:

clickup = Clickup.new(foo: "bar")
clickup.users.get_all # calls Users#get_all
clickup.lists.get_all # calls Lists#get_all

其实,我只是想起了一些事情...... 实际上是 的别名。这不是通常使用的东西,但从技术上讲,可以使用您想要的确切呼叫签名:::.

clickup = Clickup.new(foo: "bar")
clickup::users.get_all # calls Users#get_all
clickup::lists.get_all # calls Lists#get_all

评论

1赞 Stefan 4/29/2021
Users也应该是类——你不能实例化模块。(它们可以从实现大多数方法的基类继承)ListsCollection
0赞 engineersmnky 4/29/2021
@Stefan说的。由于 和 不定义为模块的方法,这将导致 .由于这些是模块,并且方法的签名不包括,并且这些方法未声明为模块函数,因此尝试直接调用这些方法也会引发ListUsernewNoMethodErrorselfNoMethodError