require 'singleton' module Sycamore ## # The Nothing Tree singleton class. # # The Nothing Tree is an empty Sycamore Tree, and means "there are no nodes". # # It is immutable: # - {Tree::QUERY_METHODS Query method} calls will behave like a normal, empty Tree. # - {Tree::DESTRUCTIVE_COMMAND_METHODS Pure destructive command} calls, will be ignored, i.e. being no-ops. # - But all other {Tree::COMMAND_METHODS command} calls, will raise a {NothingMutation}. # # It is the only Tree object that will return +true+ on a {#nothing?} call. # But like {Absence}, it will return +true+ on {#absent?} and +false+ on {#existent?}. # class NothingTree < Tree include Singleton ######################################################################## # Absence and Nothing predicates ######################################################################## ## # (see Tree#nothing?) # def nothing? true end ## # (see Tree#absent?) # def absent? true end ######################################################################## # CQS element access ######################################################################## # TODO: YARD should be informed about this method definitions. command_methods.each do |command_method| define_method command_method do |*args| raise NothingMutation, 'attempt to change the Nothing tree' end end # TODO: YARD should be informed about this method definitions. pure_destructive_command_methods.each do |command_method| define_method(command_method) { |*args| self } end def child_of(node) self end def to_native_object(sleaf_child_as: nil, **args) sleaf_child_as end ## # A string representation of the Nothing tree. # # @return [String] # def to_s 'Tree[Nothing]' end ## # A developer-friendly string representation of the Nothing tree. # # @return [String] # def inspect '#' end def freeze super end ######################################################################## # Equality ######################################################################## ## # Checks if the given object is an empty tree. # # @return [Boolean] # def ==(other) (other.is_a?(Tree) or other.is_a?(Absence)) and other.empty? end ######################################################################## # Falsiness # # Sadly, in Ruby we can't do that match to reach this goal. # # see http://devblog.avdi.org/2011/05/30/null-objects-and-falsiness/ ######################################################################## ## # Try to emulate a falsey value, by negating to +true+. # # @return [Boolean] +true+ # # @see http://devblog.avdi.org/2011/05/30/null-objects-and-falsiness/ # def ! true end # def nil? # true # end ######################################################################## # Some helpers # # Ideally these would be implemented with Refinements, but since they # aren't available anywhere (I'm looking at you, JRuby), we have to be # content with this. # ######################################################################## def like?(object) object.nil? or object.equal? self end ## # @api private class NestedStringPresentation include Singleton def inspect 'n/a' end end ## # @api private NestedString = NestedStringPresentation.instance.freeze end ############################################################################ # The Nothing Tree Singleton object # Nothing = NothingTree.instance.freeze end