1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
require 'forwardable'
module Configurate
# Class encapsulating the concept of a path to a setting
class SettingPath
include Enumerable
extend Forwardable
def initialize path=[]
path = path.split(".") if path.is_a? String
@path = path
end
def initialize_copy original
super
@path = @path.clone
end
def_delegators :@path, :empty?, :length, :size, :hsh
# Whether the current path looks like a question or setter method
def is_question_or_setter?
is_question? || is_setter?
end
# Whether the current path looks like a question method
def is_question?
@path.last.to_s.end_with?("?")
end
# Whether the current path looks like a setter method
def is_setter?
@path.last.to_s.end_with?("=")
end
def each
return to_enum(:each) unless block_given?
@path.each do |component|
yield clean_special_characters(component)
end
end
[:join, :first, :last, :shift, :pop].each do |method|
define_method method do |*args|
clean_special_characters @path.public_send(method, *args)
end
end
[:<<, :unshift, :push].each do |method|
define_method method do |*args|
@path.public_send method, *args.map(&:to_s)
end
end
def to_s
join(".")
end
def ==(other)
to_s == other.to_s
end
def inspect
"<SettingPath:#{object_id.to_s(16)} path=#{to_s}:#{@path.object_id.to_s(16)} setter=#{is_setter?} question=#{is_question?}>"
end
private
def clean_special_characters value
value.to_s.chomp("?").chomp("=")
end
end
end
|