Private module methods in Ruby
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
Accessing Private Methods from Module Functions in Ruby
module_function(symbol, ...) → self
says:-
Creates module functions for the named methods. These functions may be called with the module as a receiver, and also become available as instance methods to classes that mix in the module. Module functions are copies of the original, and so may be changed independently. The instance-method versions are made private. If used with no arguments, subsequently defined methods become module functions.
You need to make sure you declare the helper method as a #private_class_method
: private
only affects instance methods.
module Party
def enjoy
puts 'hello'
end
def pooper
enjoy
end
private_class_method :enjoy
module_function :pooper
end
Party.pooper # => 'hello'
Party.enjoy # => private method `enjoy' called for Party:Module (NoMethodError)
Furthermore, you should be careful about the ordering of accessibility keywords like public
, private
, and module_function
. These do not overlap, but rather override.
module Party
module_function # Module function declarations begin
def pooper
bar
end
def bar
enjoy
end
private # Private declarations begin, module function declarations end
module_function # Private declarations end, module function declarations begin
def enjoy # Therefore, this is a module function
"Wahoo!"
end
end
Party.pooper # => "Wahoo!"
Party.bar # => "Wahoo!"
Party.enjoy # => "Wahoo!" <-- No longer private
Note here module_function
overrides the previous private
declaration.
Here some more examples when module_function
will do its job, and when not.
The module_function
definitions stop once another accessibility keyword pops up. In this example, module_function
is interrupted by public
making #pooper
a public instance method. Use of private
would similarly block module_method
.
module Party
module_function
public
def pooper
"i am pooper"
end
end
Party.pooper
# undefined method `pooper' for Party:Module (NoMethodError)
Now if the order is changed:
module Party
public
module_function
def pooper
"i am pooper"
end
end
Party.pooper # => "i am pooper"
Private module method accessible by module classes
Modules in ruby are just containers for methods and constants. Classes know nothing about the modules that they form part of and don't inherit from them. so there is no way to make a method on ´Foo´ available for all the classes that may be inside it.
This approach may give you what you want.
module Foo
module CommandRunning
def execute(*args)
# ...
end
end
class Bar
include CommandRunning
def initialize
execute('initialize', 'bar')
end
end
end
Ruby module_function, invoking module's private method, invoked in class method style on module shows error
It works when you include the module in a class, because then all of the module's methods get included in that class (the self
in module_func_a
points to MyClass
, which has also the private_b
method).
In the other situation self points to MyModule
, which does not have private_b method. If you wanted it to work both ways, you'd have to either declare private_b
as a module method as well, or simply add the line extend self
to MyModule
, so that all it's methods would become module methods.
Private class (not class method) in a Ruby module?
I haven't seen such concept so far in Ruby, but I guess you could simulate that by creating private method which would return a class created as a local variable (remember that in Ruby, a class is an object just like any other, and can be instantiated in a method and returned by it).
BTW, even private methods in Ruby aren't as private as in other languages - you can always access them using send
method. But doing that implies you know what you are doing.
How to test private helper(module) method in rspec
create a dummy class and access private method using .send(:private_method, args)
example
obj = Class.new { extend AppHelper }
obj.send(:sum, 1,2)
Overriding 3rd party private method in ruby module?
It’d be a hacky, but working approach:
ThirdPartyGem::SeeminglyUntouchable.send(
:undef_method, :hidden_interface)
ThirdPartyGem::SeeminglyUntouchable.send(
:define_method, :hidden_interface, ->(chunky){ chunky.upcase })
ThirdPartyGem::SeeminglyUntouchable.send(
:private, :hidden_interface)
Related Topics
Can't Install Pg Gem on Windows
Ruby Gem For Finding Timezone of Location
Can't Install Rails on MAC Os Catalina
Rvm 'Not Found' After Successful Usage and a Few Days Later
How to Run All Tests With Minitest
Rake "Already Initialized Constant Wfkv_" Warning
"Gem Install Rails" Fails With Dns Error
Ruby Run Shell Command in a Specific Directory
Convert Unicode Codepoint to String Character in Ruby
Convert To/From Datetime and Time in Ruby
How to Understand the Difference Between Class_Eval() and Instance_Eval()
Ruby: Class Instance Variables VS Instance Variables