如何从包含模块的类中调用Ruby模块中的静态方法?

时间:2023-01-15 18:55:50

Is it possible to declare static methods in a module in ruby?

是否可以在ruby中的模块中声明静态方法?

module Software
  def self.exit
    puts "exited"
  end
end

class Windows
  include Software

  def self.start
    puts "started"
    self.exit
  end
end

Windows.start

The example above will not print out "exited".

上面的例子不会打印出“退出”。

Is it only possible to have instance methods in a module?

是否只能在模块中使用实例方法?

4 个解决方案

#1


30  

Define your module like this (i.e. make exit an instance method in the module):

像这样定义你的模块(即退出模块中的实例方法):

module Software
  def exit
    puts "exited"
  end
end

and then use extend rather than include

然后使用extend而不是include

class Windows
  extend Software
  # your self.start method as in the question
end

In use:

正在使用:

irb(main):016:0> Windows.start
started
exited
=> nil

Explanation

说明

obj.extend(module, ...) adds to obj the instance methods from each module given as a parameter

obj.extend(module,...)将obj作为参数给出的每个模块中的实例方法添加到obj中

...so when used within the context of a class definition (with the class itself as the receiver) the methods become class methods.

...因此,当在类定义的上下文中使用(类本身作为接收者)时,方法将成为类方法。

#2


16  

Put your class methods in a nested module, and then override the "included" hook. This hook is called anytime your module is included. Inside the hook, add the class methods to whomever did the include:

将您的类方法放在嵌套模块中,然后覆盖“包含”钩子。只要包含模块,就会调用此挂钩。在钩子内部,将类方法添加到包含的任何人:

module Foo

  def self.included(o)
    o.extend(ClassMethods)
  end

  module ClassMethods

    def foo
      'foo'
    end

  end

end

Now any class including Foo gets a class method named foo:

现在任何包括Foo的类都会获得一个名为foo的类方法:

class MyClass
  include Foo
end

p MyClass.foo    # "foo"

Any non-class methods may be defined in Foo as usual.

任何非类方法都可以像往常一样在Foo中定义。

#3


2  

Two things need to change to be able to call Windows.exit:

需要更改两件事才能调用Windows.exit:

  1. Software#exit needs to be an instance method
  2. 软件#exort需要是一个实例方法
  3. Windows needs to extend Software, not include it.
  4. Windows需要扩展软件,而不是包含它。

This is because extending another module puts that module's instance methods as the current module's class methods, whereas includeing a module puts the methods as new instance methods.

这是因为扩展另一个模块将该模块的实例方法作为当前模块的类方法,而包含模块将方法作为新的实例方法。

module Software
    def exit
        puts "exited"
    end
end

class Windows
    extend Software

    def self.start
        puts "started"
        self.exit
    end

end

Windows.start

Output is:

输出是:

started
exited

#4


0  

It is possible to include static methods in a module:

可以在模块中包含静态方法:

module Software

  def self.exit
    puts "exited"

  end
end

Software.exit

Running this prints 'exited' as expected.

运行此按预期打印'退出'。

#1


30  

Define your module like this (i.e. make exit an instance method in the module):

像这样定义你的模块(即退出模块中的实例方法):

module Software
  def exit
    puts "exited"
  end
end

and then use extend rather than include

然后使用extend而不是include

class Windows
  extend Software
  # your self.start method as in the question
end

In use:

正在使用:

irb(main):016:0> Windows.start
started
exited
=> nil

Explanation

说明

obj.extend(module, ...) adds to obj the instance methods from each module given as a parameter

obj.extend(module,...)将obj作为参数给出的每个模块中的实例方法添加到obj中

...so when used within the context of a class definition (with the class itself as the receiver) the methods become class methods.

...因此,当在类定义的上下文中使用(类本身作为接收者)时,方法将成为类方法。

#2


16  

Put your class methods in a nested module, and then override the "included" hook. This hook is called anytime your module is included. Inside the hook, add the class methods to whomever did the include:

将您的类方法放在嵌套模块中,然后覆盖“包含”钩子。只要包含模块,就会调用此挂钩。在钩子内部,将类方法添加到包含的任何人:

module Foo

  def self.included(o)
    o.extend(ClassMethods)
  end

  module ClassMethods

    def foo
      'foo'
    end

  end

end

Now any class including Foo gets a class method named foo:

现在任何包括Foo的类都会获得一个名为foo的类方法:

class MyClass
  include Foo
end

p MyClass.foo    # "foo"

Any non-class methods may be defined in Foo as usual.

任何非类方法都可以像往常一样在Foo中定义。

#3


2  

Two things need to change to be able to call Windows.exit:

需要更改两件事才能调用Windows.exit:

  1. Software#exit needs to be an instance method
  2. 软件#exort需要是一个实例方法
  3. Windows needs to extend Software, not include it.
  4. Windows需要扩展软件,而不是包含它。

This is because extending another module puts that module's instance methods as the current module's class methods, whereas includeing a module puts the methods as new instance methods.

这是因为扩展另一个模块将该模块的实例方法作为当前模块的类方法,而包含模块将方法作为新的实例方法。

module Software
    def exit
        puts "exited"
    end
end

class Windows
    extend Software

    def self.start
        puts "started"
        self.exit
    end

end

Windows.start

Output is:

输出是:

started
exited

#4


0  

It is possible to include static methods in a module:

可以在模块中包含静态方法:

module Software

  def self.exit
    puts "exited"

  end
end

Software.exit

Running this prints 'exited' as expected.

运行此按预期打印'退出'。