Private module methods in Ruby

后端 未结 9 1059
深忆病人
深忆病人 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 07:11
    module Writer
      class << self
        def output(s)
          puts upcase(s)
        end
    
        private
    
        def upcase(s)
          s.upcase
        end
      end
    end
    
    Writer.output "Hello World"
    # -> HELLO WORLD
    
    Writer.upcase "Hello World"
    # -> so.rb:16:in `<main>': private method `upcase' called for Writer:Module (NoMethodError)
    
    0 讨论(0)
  • 2020-12-04 07:11

    What's about storing methods as lambdas within class variables/constants?

    module MyModule
      @@my_secret_method = lambda {
        # ...
      }
      # ...
    end
    

    For test:
    UPD: huge update of this code after 6 years shows cleaner way to declare private method d

    module A
      @@L = lambda{ "@@L" }
      def self.a ; @@L[] ; end
      def self.b ; a ; end
    
      class << self
        def c ; @@L[] ; end
        private
        def d ; @@L[] ; end
      end
      def self.e ; c ; end
      def self.f ; self.c ; end
      def self.g ; d ; end
      def self.h ; self.d ; end
    
      private
      def self.i ; @@L[] ; end
      class << self
        def j ; @@L[] ; end
      end
    
      public
      def self.k ; i ; end
      def self.l ; self.i ; end
      def self.m ; j ; end
      def self.n ; self.j ; end
    end
    
    for expr in %w{ A.a A.b A.c A.d A.e A.f A.g A.h A.i A.j A.k A.l A.m A.n }
      puts "#{expr} => #{begin ; eval expr ; rescue => e ; e ; end}"
    end
    

    Here we see that:

    A.a => @@L
    A.b => @@L
    A.c => @@L
    A.d => private method `d' called for A:Module
    A.e => @@L
    A.f => @@L
    A.g => @@L
    A.h => private method `d' called for A:Module
    A.i => @@L
    A.j => @@L
    A.k => @@L
    A.l => @@L
    A.m => @@L
    A.n => @@L
    

    1) @@L can not be accesses from outside but is accessible from almost everywhere
    2) class << self ; private ; def successfully makes the method d inaccessible from outside and from inside with self. but not without it -- this is weird
    3) private ; self. and private ; class << self do not make methods private -- they are accessible both with and without self.

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

    I think the best way (and mostly how existing libs are written) to do this is by creating a class within the module that deals with all the logic, and the module just provides a convenient method, e.g.

    module GTranslate
      class Translator
        def perform( text ); translate( text ); end
    
        private
    
        def translate( text )
          # do some private stuff here
        end
      end
    
      def self.translate( text )
        t = Translator.new
        t.perform( text )
      end
    end
    
    0 讨论(0)
提交回复
热议问题