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 74 75 76 77 78 79 80 81 82 83 84 85
|
# frozen_string_literal: true
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 question_action_or_setter?
question? || action? || setter?
end
# Whether the current path looks like a question method
def question?
@path.last.to_s.end_with?("?")
end
# Whether the current path looks like an action method
def action?
@path.last.to_s.end_with?("!")
end
# Whether the current path looks like a setter method
def 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
%i[join first last shift pop].each do |method|
define_method method do |*args|
clean_special_characters @path.public_send(method, *args)
end
end
%i[<< 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=#{self}:#{@path.object_id.to_s(16)} "\
"question=#{question?} "\
"action=#{action?} "\
"setter=#{setter?}>"
end
private
def clean_special_characters value
value.to_s.chomp("?").chomp("=")
end
end
end
|