Can I invoke an instance method on a Ruby module without including it?

前端 未结 10 1342
情歌与酒
情歌与酒 2020-12-07 07:37

Background:

I have a module which declares a number of instance methods

module UsefulThings
  def get_file; ...
  def delete_file; ...

  def forma         


        
10条回答
  •  感动是毒
    2020-12-07 07:54

    After almost 9 years here's a generic solution:

    module CreateModuleFunctions
      def self.included(base)
        base.instance_methods.each do |method|
          base.module_eval do
            module_function(method)
            public(method)
          end
        end
      end
    end
    
    RSpec.describe CreateModuleFunctions do
      context "when included into a Module" do
        it "makes the Module's methods invokable via the Module" do
          module ModuleIncluded
            def instance_method_1;end
            def instance_method_2;end
    
            include CreateModuleFunctions
          end
    
          expect { ModuleIncluded.instance_method_1 }.to_not raise_error
        end
      end
    end
    

    The unfortunate trick you need to apply is to include the module after the methods have been defined. Alternatively you may also include it after the context is defined as ModuleIncluded.send(:include, CreateModuleFunctions).

    Or you can use it via the reflection_utils gem.

    spec.add_dependency "reflection_utils", ">= 0.3.0"
    
    require 'reflection_utils'
    include ReflectionUtils::CreateModuleFunctions
    

提交回复
热议问题