【问题标题】:Is there a way to use class method in a module without extend it in rails?有没有办法在模块中使用类方法而不在 Rails 中扩展它?
【发布时间】:2018-02-27 19:37:38
【问题描述】:

目前我有一个这样的模块:

module MyModule
  def A

  end

  .....

end

我有一个模型,我想将该方法 A 用作类方法。但是,问题是我只需要那个 A 方法。如果我扩展它,我会将其他不必要的类方法扩展到我的模型中。因此,我有没有办法像 MyModule.A 那样做某事,而无需像这样重写模块:

module MyModule
  def A
    ...
  end

  def self.A
    ...
  end

  .....

end

如果我这样做,那就是在重复自己。我仍然觉得在 Rails 中有更好的方法。

【问题讨论】:

  • module_function :A :: 旁注:你不应该调用大写的方法;没有什么可以阻止你这样做,但是 ruby​​ 有一个约定,在非常特殊的情况下使用大写名称,例如 Kernel#Integer 和 family。
  • 冷,请您将我的问题作为单独的帖子重新回答,以便我接受您的回答?
  • extend 只引入模块的实例方法(是的,这就是它们的名称,即使模块没有实例)作为类方法。 extend 对模块的类方法没有任何作用(include 也没有)。因此,如果A(我们称它为a)是模块唯一的实例方法,则无事可做。

标签: ruby-on-rails ruby class oop


【解决方案1】:

使用Module#module_function 使单个函数成为模块函数:

module M
  def m1; puts "m1"; end
  def m2; puts "m2"; end
  module_function :m2
end

或:

module M
  def m1; puts "m1"; end
module_function # from now on all functions are defined as module_functions
  def m2; puts "m2"; end
end

M.m1 #⇒ NoMethodError: undefined method `m1' for M:Module
M.m2 #⇒ "m2"

【讨论】:

  • module_function 是一个很棒的发现。它特别有用,因为我经常会有只有具有“module_functions”的模块,所以我只需在模块顶部添加module_function,并且所有定义的方法都可以在类级别访问,而必须单独使用module_functionself.。不错。
  • @JoshuaPinter 如果您需要一个仅定义类方法的静态模块,则最好在方法周围使用class << self ... end,因为module_function 使实例方法兼作类方法好吧,留下一个实例方法。与模块定义最后的extend self基本相同。
【解决方案2】:

是的,您可以将其定义为module_function,然后您应该可以使用模块名称访问它。

例如:

module Mod
  def my_method
    100
  end

  def self.my_method_1
    200
  end
  module_function :my_method
end

Mod.my_method
# => 100
Mod.my_method_1
# => 200

注意:不需要在module_function中添加自定义方法,可以直接访问。但没有自我定义的方法

需要它

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多