Private module methods in Ruby

后端 未结 9 1058
深忆病人
深忆病人 2020-12-04 06:21

I have a two part question

Best-Practice

  • I have an algorithm that performs some operation on a data structure using the public interfa
相关标签:
9条回答
  • 2020-12-04 06:56

    This method won't allow sharing data with the private methods unless you explicitly pass the data by method parameters.

    module Thing
      extend self
    
      def pub
        puts priv(123)
      end
    
      private
      
      def priv(value)
        puts "Private method with value #{value}"
      end
    end
    
    Thing.pub
    # "Private method with value 123"
    
    Thing.priv
    # NoMethodError (private method `priv' called for Thing:Module)
    
    0 讨论(0)
  • 2020-12-04 07:03

    Unfortunately, private only applies to instance methods. The general way to get private "static" methods in a class is to do something like:

    class << self
      private
    
      def foo()
       ....
      end
    end
    

    Admittedly I haven't played with doing this in modules.

    0 讨论(0)
  • 2020-12-04 07:06

    A nice way is like this

    module MyModule
      class << self
        def public_method
          # you may call the private method here
          tmp = private_method
          :public
        end
    
        private def private_method
          :private
        end
      end
    end
    
    # calling from outside the module
    puts MyModule::public_method
    
    0 讨论(0)
  • 2020-12-04 07:07

    Make a private module or class

    Constants are never private. However, it's possible to create a module or class without assigning it to a constant.

    So an alternative to :private_class_method is to create a private module or class and define public methods on it.

    module PublicModule
      def self.do_stuff(input)
        @private_implementation.do_stuff(input)
      end
    
      @private_implementation = Module.new do
        def self.do_stuff(input)
          input.upcase # or call other methods on module
        end
      end
    end
    

    Usage:

    PublicModule.do_stuff("whatever") # => "WHATEVER"
    

    See the docs for Module.new and Class.new.

    0 讨论(0)
  • 2020-12-04 07:08

    You can use the "included" method to do fancy things when a module is mixed in. This does about what you want I think:

    module Foo
      def self.included(base)
        class << base 
          def public_method
            puts "public method"
          end
          def call_private
            private_method
          end
          private
          def private_method
            puts "private"
          end
        end
      end
    end
    
    class Bar
      include Foo
    end
    
    Bar.public_method
    
    begin
      Bar.private_method
    rescue
      puts "couldn't call private method"
    end
    
    Bar.call_private
    
    0 讨论(0)
  • 2020-12-04 07:09

    There's also Module.private_class_method, which arguably expresses more intent.

    module Foo
      def self.included(base)
        base.instance_eval do
          def method_name
            # ...
          end
          private_class_method :method_name
        end
      end
    end
    

    For the code in the question:

    module Thing
      def self.pub; puts "Public method"; end
      def self.priv; puts "Private method"; end
      private_class_method :priv
    end
    

    Ruby 2.1 or newer:

    module Thing
      def self.pub; puts "Public method"; end
      private_class_method def self.priv; puts "Private method"; end
    end
    
    0 讨论(0)
提交回复
热议问题