-
-
Save alloy/4267777 to your computer and use it in GitHub Desktop.
Define hookable API in module that’s included, this way other clients can include a module that overrides those hooks. Because including modules inserts the methods in the ancestor lookup chain (i.e. the power of Ruby), this allows the use of super etc.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module APIExposable | |
def expose_api(mod = nil, &block) | |
if mod.nil? | |
if block.nil? | |
raise "Either a module or a block that's used to create a module is required." | |
else | |
mod = Module.new(&block) | |
end | |
elsif mod && block | |
raise "Only a module *or* is required, not both." | |
end | |
include mod | |
end | |
alias_method :override_api, :expose_api | |
end | |
module API | |
def execute(command) | |
puts command | |
end | |
end | |
class Downloader | |
extend APIExposable | |
expose_api API | |
def download! | |
execute('git clone URL') | |
end | |
end | |
d = Downloader.new | |
d.download! | |
class Downloader | |
override_api do | |
def execute(command) | |
puts "\nExecuting:" | |
super | |
end | |
end | |
end | |
d.download! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment