Last active
January 1, 2016 18:59
-
-
Save trestrantham/8187727 to your computer and use it in GitHub Desktop.
Adding a before filter to module instance methods
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
# All Walkman commands require the Player to be running so | |
# let's raise an error if it's not | |
class Walkman | |
module Commands | |
def self.included(base) | |
base.extend ClassMethods | |
base.instance_methods(false).each do |method_name| | |
base.add_player_check(method_name) | |
end | |
# check every method added to see if we need to create | |
# a before filter for it or not | |
base.instance_eval do | |
def method_added(name) | |
# remove our prefix(es) | |
name = name.to_s | |
name.slice!("old_") | |
# check if we've already defined new methods | |
if !method_defined?("old_#{name}") | |
add_player_check(name.to_sym) | |
end | |
end | |
end | |
end | |
module ClassMethods | |
# create a before filter that checks if the player is running | |
# by creating a new method with our filter and aliasing the old | |
def add_player_check(name) | |
class_eval do | |
unless method_defined?("old_#{name}") | |
alias_method "old_#{name}".to_sym, name | |
original_method = instance_method(name) | |
define_method(name) do |*args, &block| | |
raise "Player is not running" unless player.running? | |
original_method.bind(self).call(*args, &block) | |
end | |
end | |
end | |
end | |
end | |
end | |
end | |
class Walkman | |
module Commands | |
module Controls | |
include Walkman::Commands | |
def play | |
puts "play" | |
end | |
end | |
end | |
end | |
class Walkman | |
include Commands::Controls | |
end | |
walkman = Walkman.new | |
walkman.player.running? # => false | |
walkman.play # => RuntimeError: Player is not running | |
# start player | |
walkman.player.running? # => true | |
walkman.play # => "play" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment