Skip to content

Instantly share code, notes, and snippets.

@ippeiukai
Created November 24, 2015 07:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ippeiukai/5f83fdeb3a1f83b03d36 to your computer and use it in GitHub Desktop.
Save ippeiukai/5f83fdeb3a1f83b03d36 to your computer and use it in GitHub Desktop.
Module functions on steroid. This allows you to define a set of methods as public module methods and private instance methods while keeping private dependencies private.
# module FooBar
# extend DelegatedModuleFunction
#
# define_delegated_module_functions do
#
# def foo_bar
# 'Foo' + bar
# end
#
# private
#
# def bar
# 'Bar'
# end
#
# end
# end
#
# FooBar.foo_bar # => 'FooBar'
# FooBar.bar # => NoMethodError: private method `bar' called
# klass = Class.new { include FooBar }
# klass.foo_bar # => NoMethodError: undefined method `foo_bar'
# obj = klass.new
# obj.foo_bar # => NoMethodError: private method `foo_bar' called
# obj.instance_exec { foo_bar } # => 'FooBar'
# obj.instance_exec { bar } # => NoMethodError: undefined method `bar'
#
module DelegatedModuleFunction
private
def define_delegated_module_functions(&block)
impl = Module.new(&block)
delegatee = Object.new
delegatee.extend(impl)
methods = impl.instance_methods
delegatee_const_name = "ModuleFunctionsDelegatee_#{SecureRandom.hex(8)}"
self.const_set delegatee_const_name, delegatee
delegate *methods, to: delegatee_const_name
module_function *methods
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment