Skip to content

Instantly share code, notes, and snippets.

@irridescentrambler
Last active September 11, 2019 12:25
Show Gist options
  • Save irridescentrambler/8bccc15a94052dfc5bc999ee75bb97f1 to your computer and use it in GitHub Desktop.
Save irridescentrambler/8bccc15a94052dfc5bc999ee75bb97f1 to your computer and use it in GitHub Desktop.
module Configurable
def is_a
wrapper(true)
end
def is_not_a
wrapper(false)
end
private
def wrapper(wrapper_type)
wrapper_type ? positive_wrapper : negative_wrapper
end
def positive_wrapper
@positive_wrapper ||= HumanWrapper.new(self, true)
end
def negative_wrapper
@negative_wrapper ||= HumanWrapper.new(self, false)
end
class HumanWrapper
attr_accessor :base, :wrapper_type
def initialize(base, wrapper_type)
@base = base
@wrapper_type = wrapper_type
end
def method_missing(method_name)
result = wrapper_type
base.instance_eval do
define_singleton_method("#{ method_name}?") do
result
end
end
end
end
end
class Human
include Configurable
end
john = Human.new
#<Human:0x00007f8f91091488>
john.is_a.developer
#=> :developer?
john.developer?
#=> true
john.is_not_a.financial_adviser
#=> :financial_adviser?
john.financial_adviser?
#=> false
john.method(:developer?).source_location
#=> ['source_location_demo.rb', 34]
john.method(:financial_adviser?).source_location
#=> ['source_location_demo.rb', 34]
john.method(:developer?).source.owner
#=> #<Class:#<Human:0x00007f8f91091488>>
# Because #developer? is a singleton method.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment