Last active
December 13, 2015 17:09
-
-
Save glucero/4945872 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 Extendable | |
def unique_instance_methods | |
instance_methods.sort - superclass.instance_methods.sort | |
end | |
def extend_methods(*methods) | |
methods.each do |method_extender| | |
method = instance_method(method_extender) | |
send(:define_method, method_extender) do | |
yield method.bind(self) | |
end | |
end | |
end | |
def printable_methods(*methods) # ^caller[3] | |
extend_methods(*methods) do |method| # caller[2] | |
method.call.tap do |response| # caller[1] | |
$stdout.puts "caller: #{caller[3][/`(.+)'/, 1]}" # caller[0] | |
$stdout.puts "method: #{method.receiver.class}##{method.name}" | |
$stdout.puts "response: #{response.inspect}" | |
end | |
end | |
end | |
def rescuable_methods(*methods) | |
extend_methods(*methods) do |method| | |
begin | |
method.call | |
rescue Exception => error | |
$stderr.puts error.message, *error.backtrace | |
end | |
end | |
end | |
def countable_methods(*methods) | |
send(:define_method, :method_counter) do | |
@method_counter ||= Hash.new(0) | |
end | |
extend_methods(*methods) do |method| | |
method.receiver.method_counter[method.name] += 1 | |
method.call | |
end | |
end | |
def chainable_methods(*methods) | |
extend_methods(*methods) do |method| | |
method.call | |
method.receiver | |
end | |
end | |
end |
This file contains hidden or 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
class Dog | |
attr_reader :name, :age | |
def alive? | |
!!@age | |
end | |
def born! | |
@age = 0 | |
end | |
def advance | |
@age += 1 | |
end | |
def initialize(name) | |
@name = name | |
end | |
extend Extendable | |
chainable_methods :advance | |
countable_methods :alive? | |
printable_methods :name, :born! | |
extend_methods(:advance) do |method| | |
method.receiver.alive? ? method.call : raise("#{name} has not been born yet.") | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
spot = Dog.new('Spot')
spot.name
spot.name.upcase.to_sym
spot.advance
spot.born!
spot.advance.advance.advance.advance.advance
spot.method_counter