Skip to content

Instantly share code, notes, and snippets.

@leandro
Created April 13, 2023 00:23
Show Gist options
  • Save leandro/7e961c5ee89ace10eb7d8d8cb74ecddd to your computer and use it in GitHub Desktop.
Save leandro/7e961c5ee89ace10eb7d8d8cb74ecddd to your computer and use it in GitHub Desktop.
A different approach, compared to using `Module#module_function`
# The idea here is to make all the methods below accessible through the module
# itself and through the classes including the module, but having the methods
# publicly available both as instance and as class methods.
module A
def self.abc = 123
def self.xyz = 456
def self.append_features(klass)
methods_being_added = singleton_methods - [:append_features]
delegation_setter = ->(mod, methods) { delegate *methods, to: mod }
[klass.singleton_class, klass].each do |receiver|
receiver.class_exec(self, methods_being_added, &delegation_setter)
end
end
end
class B
include A
end
# Methods accessible through the module itself:
[A.abc, A.xyz] # => [123, 456]
# Methods accessible as instance methods in the class that has the module included:
[B.new.abc, B.new.xyz] # => [123, 456]
# And last but not least, the same methods accessible through class methods:
[B.abc, B.xyz] # => [123, 456]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment