def add_child(child_, ranges_=nil)
if child_._descendant_fields.include?(self)
raise Errors::CircularDescendantError
end
@children << child_
if ranges_.nil?
if @default_child
raise Errors::RangeOverlapError("Cannot have more than one default child")
end
@default_child = child_
return
end
ranges_ = [ranges_] unless ranges_.is_a?(Array)
ranges_.each do |range_|
case range_
when ::Range
if range_.exclude_end?
raise Errors::RangeSpecificationError("Ranges must be inclusive")
end
normalized_range_ = [range_.first, range_.last]
when ::Array
if range_.size != 2
raise Errors::RangeSpecificationError("Range array should have two elements")
end
normalized_range_ = range_.dup
when ::String, ::Symbol, ::Integer
normalized_range_ = [range_, range_]
else
raise Errors::RangeSpecificationError("Unrecognized range type #{range_.class}")
end
normalized_range_.map! do |elem_|
if elem_.nil?
elem_
else
case @type
when :integer
elem_.to_i
when :string
elem_.to_s
when :symbol
begin
elem_.to_sym
rescue
raise Errors::RangeSpecificationError("Bad symbol value: #{elem_.inspect}")
end
end
end
end
normalized_range_ << child_
@ranges ||= Array.new
insert_index_ = @ranges.size
@ranges.each_with_index do |r_, i_|
if normalized_range_[0] && r_[1]
cmp_ = compare_values(normalized_range_[0], r_[1])
if cmp_.nil?
raise Errors::RangeSpecificationError
end
if cmp_ > 0
next
end
end
if normalized_range_[1] && r_[0]
cmp_ = compare_values(normalized_range_[1], r_[0])
if cmp_.nil?
raise Errors::RangeSpecificationError
end
if cmp_ < 0
insert_index_ = i_
break
end
end
raise Errors::RangeOverlapError
end
@ranges.insert(insert_index_, normalized_range_)
end
end