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

Background:

I have a module which declares a number of instance methods

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

  def format_text(x); ...
end

And I want to call some of these methods from within a class. How you normally do this in ruby is like this:

class UsefulWorker
  include UsefulThings

  def do_work
    format_text("abc")
    ...
  end
end

Problem

include UsefulThings brings in all of the methods from UsefulThings . In this case I only want format_text and explicitly do not want get_file and delete_file .

I can see several possible solutions to this:

  • Somehow invoke the method directly on the module without including it anywhere
  • I don't know how/if this can be done. (Hence this question)
  • Somehow include Usefulthings and only bring in some of it's methods
  • I also don't know how/if this can be done
  • Create a proxy class, include UsefulThings in that, then delegate format_text to that proxy instance
  • This would work, but anonymous proxy classes are a hack. Yuck.
  • Split up the module into 2 or more smaller modules
  • This would also work, and is probably the best solution I can think of, but I'd prefer to avoid it as I'd end up with a proliferation of dozens and dozens of modules - managing this would be burdensome
  • Why are there lots of unrelated functions in a single module? It's ApplicationHelper from a rails app, which our team has de-facto decided on as the dumping ground for anything not specific enough to belong anywhere else. Mostly standalone utility methods that get used everywhere. I could break it up into seperate helpers, but there'd be 30 of them, all with 1 method each... this seems unproductive


    If a method on a module is turned into a module function you can simply call it off of Mods as if it had been declared as

    module Mods
      def self.foo
         puts "Mods.foo(self)"
      end
    end
    

    The module_function approach below will avoid breaking any classes which include all of Mods.

    module Mods
      def foo
        puts "Mods.foo"
      end
    end
    
    class Includer
      include Mods
    end
    
    Includer.new.foo
    
    Mods.module_eval do
      module_function(:foo)
      public :foo
    end
    
    Includer.new.foo # this would break without public :foo above
    
    class Thing
      def bar
        Mods.foo
      end
    end
    
    Thing.new.bar  
    

    However, I'm curious why a set of unrelated functions are all contained within the same module in the first place?

    Edited to show that includes still work if public :foo is called after module_function :foo


    我认为最简单的方法就是抛弃单个调用(不改变现有模块或创建新模块),如下所示:

    Class.new.extend(UsefulThings).get_file
    

    如果你“拥有”模块的另一种方法是使用module_function

    module UsefulThings
      def a
        puts "aaay"
      end
      module_function :a
    
      def b
        puts "beee"
      end
    end
    
    def test
      UsefulThings.a
      UsefulThings.b # Fails!  Not a module method
    end
    
    test
    
    链接地址: http://www.djcxy.com/p/44834.html

    上一篇: 为什么在Ruby方法中使用感叹号?

    下一篇: 我可以在不包含它的情况下调用Ruby模块上的实例方法吗?