metaractor-sycamore 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.editorconfig +24 -0
 - data/.envrc +3 -0
 - data/.github/workflows/specs.yml +13 -0
 - data/.gitignore +16 -0
 - data/.rspec +6 -0
 - data/.ruby-version +1 -0
 - data/.yardopts +13 -0
 - data/AUTHORS +2 -0
 - data/CHANGELOG.md +88 -0
 - data/CONTRIBUTING.md +5 -0
 - data/CREDITS +0 -0
 - data/Gemfile +12 -0
 - data/LICENSE.txt +22 -0
 - data/README.md +571 -0
 - data/Rakefile +36 -0
 - data/VERSION +1 -0
 - data/bin/console +7 -0
 - data/bin/setup +8 -0
 - data/devenv.lock +210 -0
 - data/devenv.nix +25 -0
 - data/devenv.yaml +8 -0
 - data/lib/outstand_sycamore.rb +1 -0
 - data/lib/sycamore/absence.rb +179 -0
 - data/lib/sycamore/exceptions.rb +16 -0
 - data/lib/sycamore/extension/nothing.rb +4 -0
 - data/lib/sycamore/extension/path.rb +7 -0
 - data/lib/sycamore/extension/tree.rb +4 -0
 - data/lib/sycamore/extension.rb +2 -0
 - data/lib/sycamore/nothing.rb +157 -0
 - data/lib/sycamore/path.rb +266 -0
 - data/lib/sycamore/path_root.rb +43 -0
 - data/lib/sycamore/stree.rb +4 -0
 - data/lib/sycamore/tree.rb +1469 -0
 - data/lib/sycamore/version.rb +28 -0
 - data/lib/sycamore.rb +13 -0
 - data/support/doctest_helper.rb +2 -0
 - data/support/travis.sh +6 -0
 - data/sycamore.gemspec +29 -0
 - metadata +152 -0
 
    
        data/devenv.lock
    ADDED
    
    | 
         @@ -0,0 +1,210 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            {
         
     | 
| 
      
 2 
     | 
    
         
            +
              "nodes": {
         
     | 
| 
      
 3 
     | 
    
         
            +
                "devenv": {
         
     | 
| 
      
 4 
     | 
    
         
            +
                  "locked": {
         
     | 
| 
      
 5 
     | 
    
         
            +
                    "dir": "src/modules",
         
     | 
| 
      
 6 
     | 
    
         
            +
                    "lastModified": 1686054274,
         
     | 
| 
      
 7 
     | 
    
         
            +
                    "narHash": "sha256-93aebyN7EMmeFFXisFIvp28UEbrozu79vd3pKPjvNR0=",
         
     | 
| 
      
 8 
     | 
    
         
            +
                    "owner": "cachix",
         
     | 
| 
      
 9 
     | 
    
         
            +
                    "repo": "devenv",
         
     | 
| 
      
 10 
     | 
    
         
            +
                    "rev": "c51a56bac8853c019241fe8d821c0a0d82422835",
         
     | 
| 
      
 11 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 12 
     | 
    
         
            +
                  },
         
     | 
| 
      
 13 
     | 
    
         
            +
                  "original": {
         
     | 
| 
      
 14 
     | 
    
         
            +
                    "dir": "src/modules",
         
     | 
| 
      
 15 
     | 
    
         
            +
                    "owner": "cachix",
         
     | 
| 
      
 16 
     | 
    
         
            +
                    "repo": "devenv",
         
     | 
| 
      
 17 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 18 
     | 
    
         
            +
                  }
         
     | 
| 
      
 19 
     | 
    
         
            +
                },
         
     | 
| 
      
 20 
     | 
    
         
            +
                "flake-compat": {
         
     | 
| 
      
 21 
     | 
    
         
            +
                  "flake": false,
         
     | 
| 
      
 22 
     | 
    
         
            +
                  "locked": {
         
     | 
| 
      
 23 
     | 
    
         
            +
                    "lastModified": 1673956053,
         
     | 
| 
      
 24 
     | 
    
         
            +
                    "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
         
     | 
| 
      
 25 
     | 
    
         
            +
                    "owner": "edolstra",
         
     | 
| 
      
 26 
     | 
    
         
            +
                    "repo": "flake-compat",
         
     | 
| 
      
 27 
     | 
    
         
            +
                    "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
         
     | 
| 
      
 28 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 29 
     | 
    
         
            +
                  },
         
     | 
| 
      
 30 
     | 
    
         
            +
                  "original": {
         
     | 
| 
      
 31 
     | 
    
         
            +
                    "owner": "edolstra",
         
     | 
| 
      
 32 
     | 
    
         
            +
                    "repo": "flake-compat",
         
     | 
| 
      
 33 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 34 
     | 
    
         
            +
                  }
         
     | 
| 
      
 35 
     | 
    
         
            +
                },
         
     | 
| 
      
 36 
     | 
    
         
            +
                "flake-compat_2": {
         
     | 
| 
      
 37 
     | 
    
         
            +
                  "flake": false,
         
     | 
| 
      
 38 
     | 
    
         
            +
                  "locked": {
         
     | 
| 
      
 39 
     | 
    
         
            +
                    "lastModified": 1673956053,
         
     | 
| 
      
 40 
     | 
    
         
            +
                    "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
         
     | 
| 
      
 41 
     | 
    
         
            +
                    "owner": "edolstra",
         
     | 
| 
      
 42 
     | 
    
         
            +
                    "repo": "flake-compat",
         
     | 
| 
      
 43 
     | 
    
         
            +
                    "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
         
     | 
| 
      
 44 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 45 
     | 
    
         
            +
                  },
         
     | 
| 
      
 46 
     | 
    
         
            +
                  "original": {
         
     | 
| 
      
 47 
     | 
    
         
            +
                    "owner": "edolstra",
         
     | 
| 
      
 48 
     | 
    
         
            +
                    "repo": "flake-compat",
         
     | 
| 
      
 49 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 50 
     | 
    
         
            +
                  }
         
     | 
| 
      
 51 
     | 
    
         
            +
                },
         
     | 
| 
      
 52 
     | 
    
         
            +
                "flake-utils": {
         
     | 
| 
      
 53 
     | 
    
         
            +
                  "locked": {
         
     | 
| 
      
 54 
     | 
    
         
            +
                    "lastModified": 1667395993,
         
     | 
| 
      
 55 
     | 
    
         
            +
                    "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
         
     | 
| 
      
 56 
     | 
    
         
            +
                    "owner": "numtide",
         
     | 
| 
      
 57 
     | 
    
         
            +
                    "repo": "flake-utils",
         
     | 
| 
      
 58 
     | 
    
         
            +
                    "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
         
     | 
| 
      
 59 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 60 
     | 
    
         
            +
                  },
         
     | 
| 
      
 61 
     | 
    
         
            +
                  "original": {
         
     | 
| 
      
 62 
     | 
    
         
            +
                    "owner": "numtide",
         
     | 
| 
      
 63 
     | 
    
         
            +
                    "repo": "flake-utils",
         
     | 
| 
      
 64 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 65 
     | 
    
         
            +
                  }
         
     | 
| 
      
 66 
     | 
    
         
            +
                },
         
     | 
| 
      
 67 
     | 
    
         
            +
                "flake-utils_2": {
         
     | 
| 
      
 68 
     | 
    
         
            +
                  "inputs": {
         
     | 
| 
      
 69 
     | 
    
         
            +
                    "systems": "systems"
         
     | 
| 
      
 70 
     | 
    
         
            +
                  },
         
     | 
| 
      
 71 
     | 
    
         
            +
                  "locked": {
         
     | 
| 
      
 72 
     | 
    
         
            +
                    "lastModified": 1685518550,
         
     | 
| 
      
 73 
     | 
    
         
            +
                    "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=",
         
     | 
| 
      
 74 
     | 
    
         
            +
                    "owner": "numtide",
         
     | 
| 
      
 75 
     | 
    
         
            +
                    "repo": "flake-utils",
         
     | 
| 
      
 76 
     | 
    
         
            +
                    "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef",
         
     | 
| 
      
 77 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 78 
     | 
    
         
            +
                  },
         
     | 
| 
      
 79 
     | 
    
         
            +
                  "original": {
         
     | 
| 
      
 80 
     | 
    
         
            +
                    "owner": "numtide",
         
     | 
| 
      
 81 
     | 
    
         
            +
                    "repo": "flake-utils",
         
     | 
| 
      
 82 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 83 
     | 
    
         
            +
                  }
         
     | 
| 
      
 84 
     | 
    
         
            +
                },
         
     | 
| 
      
 85 
     | 
    
         
            +
                "gitignore": {
         
     | 
| 
      
 86 
     | 
    
         
            +
                  "inputs": {
         
     | 
| 
      
 87 
     | 
    
         
            +
                    "nixpkgs": [
         
     | 
| 
      
 88 
     | 
    
         
            +
                      "pre-commit-hooks",
         
     | 
| 
      
 89 
     | 
    
         
            +
                      "nixpkgs"
         
     | 
| 
      
 90 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 91 
     | 
    
         
            +
                  },
         
     | 
| 
      
 92 
     | 
    
         
            +
                  "locked": {
         
     | 
| 
      
 93 
     | 
    
         
            +
                    "lastModified": 1660459072,
         
     | 
| 
      
 94 
     | 
    
         
            +
                    "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
         
     | 
| 
      
 95 
     | 
    
         
            +
                    "owner": "hercules-ci",
         
     | 
| 
      
 96 
     | 
    
         
            +
                    "repo": "gitignore.nix",
         
     | 
| 
      
 97 
     | 
    
         
            +
                    "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
         
     | 
| 
      
 98 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 99 
     | 
    
         
            +
                  },
         
     | 
| 
      
 100 
     | 
    
         
            +
                  "original": {
         
     | 
| 
      
 101 
     | 
    
         
            +
                    "owner": "hercules-ci",
         
     | 
| 
      
 102 
     | 
    
         
            +
                    "repo": "gitignore.nix",
         
     | 
| 
      
 103 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 104 
     | 
    
         
            +
                  }
         
     | 
| 
      
 105 
     | 
    
         
            +
                },
         
     | 
| 
      
 106 
     | 
    
         
            +
                "nixpkgs": {
         
     | 
| 
      
 107 
     | 
    
         
            +
                  "locked": {
         
     | 
| 
      
 108 
     | 
    
         
            +
                    "lastModified": 1685938391,
         
     | 
| 
      
 109 
     | 
    
         
            +
                    "narHash": "sha256-96Jw6TbWDLSopt5jqCW8w1Fc1cjQyZlhfBnJ3OZGpME=",
         
     | 
| 
      
 110 
     | 
    
         
            +
                    "owner": "NixOS",
         
     | 
| 
      
 111 
     | 
    
         
            +
                    "repo": "nixpkgs",
         
     | 
| 
      
 112 
     | 
    
         
            +
                    "rev": "31cd1b4afbaf0b1e81272ee9c31d1ab606503aed",
         
     | 
| 
      
 113 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 114 
     | 
    
         
            +
                  },
         
     | 
| 
      
 115 
     | 
    
         
            +
                  "original": {
         
     | 
| 
      
 116 
     | 
    
         
            +
                    "owner": "NixOS",
         
     | 
| 
      
 117 
     | 
    
         
            +
                    "ref": "nixpkgs-unstable",
         
     | 
| 
      
 118 
     | 
    
         
            +
                    "repo": "nixpkgs",
         
     | 
| 
      
 119 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 120 
     | 
    
         
            +
                  }
         
     | 
| 
      
 121 
     | 
    
         
            +
                },
         
     | 
| 
      
 122 
     | 
    
         
            +
                "nixpkgs-ruby": {
         
     | 
| 
      
 123 
     | 
    
         
            +
                  "inputs": {
         
     | 
| 
      
 124 
     | 
    
         
            +
                    "flake-compat": "flake-compat",
         
     | 
| 
      
 125 
     | 
    
         
            +
                    "flake-utils": "flake-utils",
         
     | 
| 
      
 126 
     | 
    
         
            +
                    "nixpkgs": [
         
     | 
| 
      
 127 
     | 
    
         
            +
                      "nixpkgs"
         
     | 
| 
      
 128 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 129 
     | 
    
         
            +
                  },
         
     | 
| 
      
 130 
     | 
    
         
            +
                  "locked": {
         
     | 
| 
      
 131 
     | 
    
         
            +
                    "lastModified": 1685159223,
         
     | 
| 
      
 132 
     | 
    
         
            +
                    "narHash": "sha256-rwHYapZEvxDJ8dw3hMGY/AE9c6qls9CifAUvObnx7e0=",
         
     | 
| 
      
 133 
     | 
    
         
            +
                    "owner": "bobvanderlinden",
         
     | 
| 
      
 134 
     | 
    
         
            +
                    "repo": "nixpkgs-ruby",
         
     | 
| 
      
 135 
     | 
    
         
            +
                    "rev": "dfaf58567eda18bad5340a9432e601d96c497943",
         
     | 
| 
      
 136 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 137 
     | 
    
         
            +
                  },
         
     | 
| 
      
 138 
     | 
    
         
            +
                  "original": {
         
     | 
| 
      
 139 
     | 
    
         
            +
                    "owner": "bobvanderlinden",
         
     | 
| 
      
 140 
     | 
    
         
            +
                    "repo": "nixpkgs-ruby",
         
     | 
| 
      
 141 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 142 
     | 
    
         
            +
                  }
         
     | 
| 
      
 143 
     | 
    
         
            +
                },
         
     | 
| 
      
 144 
     | 
    
         
            +
                "nixpkgs-stable": {
         
     | 
| 
      
 145 
     | 
    
         
            +
                  "locked": {
         
     | 
| 
      
 146 
     | 
    
         
            +
                    "lastModified": 1685801374,
         
     | 
| 
      
 147 
     | 
    
         
            +
                    "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=",
         
     | 
| 
      
 148 
     | 
    
         
            +
                    "owner": "NixOS",
         
     | 
| 
      
 149 
     | 
    
         
            +
                    "repo": "nixpkgs",
         
     | 
| 
      
 150 
     | 
    
         
            +
                    "rev": "c37ca420157f4abc31e26f436c1145f8951ff373",
         
     | 
| 
      
 151 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 152 
     | 
    
         
            +
                  },
         
     | 
| 
      
 153 
     | 
    
         
            +
                  "original": {
         
     | 
| 
      
 154 
     | 
    
         
            +
                    "owner": "NixOS",
         
     | 
| 
      
 155 
     | 
    
         
            +
                    "ref": "nixos-23.05",
         
     | 
| 
      
 156 
     | 
    
         
            +
                    "repo": "nixpkgs",
         
     | 
| 
      
 157 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 158 
     | 
    
         
            +
                  }
         
     | 
| 
      
 159 
     | 
    
         
            +
                },
         
     | 
| 
      
 160 
     | 
    
         
            +
                "pre-commit-hooks": {
         
     | 
| 
      
 161 
     | 
    
         
            +
                  "inputs": {
         
     | 
| 
      
 162 
     | 
    
         
            +
                    "flake-compat": "flake-compat_2",
         
     | 
| 
      
 163 
     | 
    
         
            +
                    "flake-utils": "flake-utils_2",
         
     | 
| 
      
 164 
     | 
    
         
            +
                    "gitignore": "gitignore",
         
     | 
| 
      
 165 
     | 
    
         
            +
                    "nixpkgs": [
         
     | 
| 
      
 166 
     | 
    
         
            +
                      "nixpkgs"
         
     | 
| 
      
 167 
     | 
    
         
            +
                    ],
         
     | 
| 
      
 168 
     | 
    
         
            +
                    "nixpkgs-stable": "nixpkgs-stable"
         
     | 
| 
      
 169 
     | 
    
         
            +
                  },
         
     | 
| 
      
 170 
     | 
    
         
            +
                  "locked": {
         
     | 
| 
      
 171 
     | 
    
         
            +
                    "lastModified": 1686050334,
         
     | 
| 
      
 172 
     | 
    
         
            +
                    "narHash": "sha256-R0mczWjDzBpIvM3XXhO908X5e2CQqjyh/gFbwZk/7/Q=",
         
     | 
| 
      
 173 
     | 
    
         
            +
                    "owner": "cachix",
         
     | 
| 
      
 174 
     | 
    
         
            +
                    "repo": "pre-commit-hooks.nix",
         
     | 
| 
      
 175 
     | 
    
         
            +
                    "rev": "6881eb2ae5d8a3516e34714e7a90d9d95914c4dc",
         
     | 
| 
      
 176 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 177 
     | 
    
         
            +
                  },
         
     | 
| 
      
 178 
     | 
    
         
            +
                  "original": {
         
     | 
| 
      
 179 
     | 
    
         
            +
                    "owner": "cachix",
         
     | 
| 
      
 180 
     | 
    
         
            +
                    "repo": "pre-commit-hooks.nix",
         
     | 
| 
      
 181 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 182 
     | 
    
         
            +
                  }
         
     | 
| 
      
 183 
     | 
    
         
            +
                },
         
     | 
| 
      
 184 
     | 
    
         
            +
                "root": {
         
     | 
| 
      
 185 
     | 
    
         
            +
                  "inputs": {
         
     | 
| 
      
 186 
     | 
    
         
            +
                    "devenv": "devenv",
         
     | 
| 
      
 187 
     | 
    
         
            +
                    "nixpkgs": "nixpkgs",
         
     | 
| 
      
 188 
     | 
    
         
            +
                    "nixpkgs-ruby": "nixpkgs-ruby",
         
     | 
| 
      
 189 
     | 
    
         
            +
                    "pre-commit-hooks": "pre-commit-hooks"
         
     | 
| 
      
 190 
     | 
    
         
            +
                  }
         
     | 
| 
      
 191 
     | 
    
         
            +
                },
         
     | 
| 
      
 192 
     | 
    
         
            +
                "systems": {
         
     | 
| 
      
 193 
     | 
    
         
            +
                  "locked": {
         
     | 
| 
      
 194 
     | 
    
         
            +
                    "lastModified": 1681028828,
         
     | 
| 
      
 195 
     | 
    
         
            +
                    "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
         
     | 
| 
      
 196 
     | 
    
         
            +
                    "owner": "nix-systems",
         
     | 
| 
      
 197 
     | 
    
         
            +
                    "repo": "default",
         
     | 
| 
      
 198 
     | 
    
         
            +
                    "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
         
     | 
| 
      
 199 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 200 
     | 
    
         
            +
                  },
         
     | 
| 
      
 201 
     | 
    
         
            +
                  "original": {
         
     | 
| 
      
 202 
     | 
    
         
            +
                    "owner": "nix-systems",
         
     | 
| 
      
 203 
     | 
    
         
            +
                    "repo": "default",
         
     | 
| 
      
 204 
     | 
    
         
            +
                    "type": "github"
         
     | 
| 
      
 205 
     | 
    
         
            +
                  }
         
     | 
| 
      
 206 
     | 
    
         
            +
                }
         
     | 
| 
      
 207 
     | 
    
         
            +
              },
         
     | 
| 
      
 208 
     | 
    
         
            +
              "root": "root",
         
     | 
| 
      
 209 
     | 
    
         
            +
              "version": 7
         
     | 
| 
      
 210 
     | 
    
         
            +
            }
         
     | 
    
        data/devenv.nix
    ADDED
    
    | 
         @@ -0,0 +1,25 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            { pkgs, ... }:
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            {
         
     | 
| 
      
 4 
     | 
    
         
            +
              # https://devenv.sh/packages/
         
     | 
| 
      
 5 
     | 
    
         
            +
              packages = with pkgs; [
         
     | 
| 
      
 6 
     | 
    
         
            +
                git
         
     | 
| 
      
 7 
     | 
    
         
            +
              ];
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              # https://devenv.sh/languages/
         
     | 
| 
      
 10 
     | 
    
         
            +
              languages.ruby.enable = true;
         
     | 
| 
      
 11 
     | 
    
         
            +
              # Uses bobvanderlinden/nixpkgs-ruby to supply any version of ruby
         
     | 
| 
      
 12 
     | 
    
         
            +
              languages.ruby.versionFile = ./.ruby-version;
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              enterShell = ''
         
     | 
| 
      
 15 
     | 
    
         
            +
                export BUNDLE_BIN="$DEVENV_ROOT/.devenv/bin"
         
     | 
| 
      
 16 
     | 
    
         
            +
                export PATH="$DEVENV_PROFILE/bin:$DEVENV_ROOT/bin:$BUNDLE_BIN:$PATH"
         
     | 
| 
      
 17 
     | 
    
         
            +
                export BOOTSNAP_CACHE_DIR="$DEVENV_ROOT/.devenv/state"
         
     | 
| 
      
 18 
     | 
    
         
            +
              '';
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              # The unix socket path can't be "too long".
         
     | 
| 
      
 21 
     | 
    
         
            +
              # Make sure it's short for when we need it.
         
     | 
| 
      
 22 
     | 
    
         
            +
              env.RUBY_DEBUG_SOCK_DIR = "/tmp/";
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              # See full reference at https://devenv.sh/reference/options/
         
     | 
| 
      
 25 
     | 
    
         
            +
            }
         
     | 
    
        data/devenv.yaml
    ADDED
    
    
| 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'sycamore'
         
     | 
| 
         @@ -0,0 +1,179 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'delegate'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sycamore
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              ##
         
     | 
| 
      
 6 
     | 
    
         
            +
              # An Absence object represents the absence of a specific child {Sycamore::Tree}.
         
     | 
| 
      
 7 
     | 
    
         
            +
              #
         
     | 
| 
      
 8 
     | 
    
         
            +
              # +Absence+ instances get created when accessing non-existent children of a
         
     | 
| 
      
 9 
     | 
    
         
            +
              # Tree with {Tree#child_of} or {Tree#child_at}.
         
     | 
| 
      
 10 
     | 
    
         
            +
              # It is not intended to be instantiated by the user.
         
     | 
| 
      
 11 
     | 
    
         
            +
              #
         
     | 
| 
      
 12 
     | 
    
         
            +
              # An +Absence+ object can be used like a normal {Sycamore::Tree}.
         
     | 
| 
      
 13 
     | 
    
         
            +
              # {Tree::QUERY_METHODS Query} and {Tree::DESTRUCTIVE_COMMAND_METHODS pure destructive command method}
         
     | 
| 
      
 14 
     | 
    
         
            +
              # calls get delegated to {Sycamore::Nothing}, i.e. will behave like an empty Tree.
         
     | 
| 
      
 15 
     | 
    
         
            +
              # On every other {Tree::COMMAND_METHODS command} calls, the +Absence+ object
         
     | 
| 
      
 16 
     | 
    
         
            +
              # gets resolved, which means the missing tree will be created, added to the
         
     | 
| 
      
 17 
     | 
    
         
            +
              # parent tree and the method call gets delegated to the now existing tree.
         
     | 
| 
      
 18 
     | 
    
         
            +
              # After the +Absence+ object is resolved all subsequent method calls are
         
     | 
| 
      
 19 
     | 
    
         
            +
              # delegated to the created tree.
         
     | 
| 
      
 20 
     | 
    
         
            +
              # The type of tree eventually created is determined by the {Tree#new_child}
         
     | 
| 
      
 21 
     | 
    
         
            +
              # implementation of the parent tree and the parent node.
         
     | 
| 
      
 22 
     | 
    
         
            +
              #
         
     | 
| 
      
 23 
     | 
    
         
            +
              class Absence < Delegator
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                ##
         
     | 
| 
      
 26 
     | 
    
         
            +
                # @api private
         
     | 
| 
      
 27 
     | 
    
         
            +
                #
         
     | 
| 
      
 28 
     | 
    
         
            +
                def initialize(parent_tree, parent_node)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  @parent_tree, @parent_node = parent_tree, parent_node
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 33 
     | 
    
         
            +
                  alias at new
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                ########################################################################
         
     | 
| 
      
 37 
     | 
    
         
            +
                # presence creation
         
     | 
| 
      
 38 
     | 
    
         
            +
                ########################################################################
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                ##
         
     | 
| 
      
 41 
     | 
    
         
            +
                # The tree object to which all method calls are delegated.
         
     | 
| 
      
 42 
     | 
    
         
            +
                #
         
     | 
| 
      
 43 
     | 
    
         
            +
                # @api private
         
     | 
| 
      
 44 
     | 
    
         
            +
                #
         
     | 
| 
      
 45 
     | 
    
         
            +
                def presence
         
     | 
| 
      
 46 
     | 
    
         
            +
                  @tree or Nothing
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                alias __getobj__ presence
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                ##
         
     | 
| 
      
 52 
     | 
    
         
            +
                # @api private
         
     | 
| 
      
 53 
     | 
    
         
            +
                #
         
     | 
| 
      
 54 
     | 
    
         
            +
                def create
         
     | 
| 
      
 55 
     | 
    
         
            +
                  @parent_tree = @parent_tree.add_node_with_empty_child(@parent_node)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  @tree = @parent_tree[@parent_node]
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                ########################################################################
         
     | 
| 
      
 60 
     | 
    
         
            +
                # Absence and Nothing predicates
         
     | 
| 
      
 61 
     | 
    
         
            +
                ########################################################################
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                ##
         
     | 
| 
      
 64 
     | 
    
         
            +
                # (see Tree#absent?)
         
     | 
| 
      
 65 
     | 
    
         
            +
                #
         
     | 
| 
      
 66 
     | 
    
         
            +
                def absent?
         
     | 
| 
      
 67 
     | 
    
         
            +
                  @tree.nil?
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                ##
         
     | 
| 
      
 71 
     | 
    
         
            +
                # (see Tree#nothing?)
         
     | 
| 
      
 72 
     | 
    
         
            +
                #
         
     | 
| 
      
 73 
     | 
    
         
            +
                def nothing?
         
     | 
| 
      
 74 
     | 
    
         
            +
                  false
         
     | 
| 
      
 75 
     | 
    
         
            +
                end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                ########################################################################
         
     | 
| 
      
 78 
     | 
    
         
            +
                # Element access
         
     | 
| 
      
 79 
     | 
    
         
            +
                ########################################################################
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                #####################
         
     | 
| 
      
 82 
     | 
    
         
            +
                #   query methods   #
         
     | 
| 
      
 83 
     | 
    
         
            +
                #####################
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                def child_of(node)
         
     | 
| 
      
 86 
     | 
    
         
            +
                  if absent?
         
     | 
| 
      
 87 
     | 
    
         
            +
                    raise InvalidNode, "#{node} is not a valid tree node" if node.is_a? Enumerable
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                    Absence.at(self, node)
         
     | 
| 
      
 90 
     | 
    
         
            +
                  else
         
     | 
| 
      
 91 
     | 
    
         
            +
                    presence.child_of(node)
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
                end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                def child_at(*path)
         
     | 
| 
      
 96 
     | 
    
         
            +
                  if absent?
         
     | 
| 
      
 97 
     | 
    
         
            +
                    # TODO: This is duplication of Tree#child_at! How can we remove it, without introducing a module for this single method or inherit from Tree?
         
     | 
| 
      
 98 
     | 
    
         
            +
                    case path.length
         
     | 
| 
      
 99 
     | 
    
         
            +
                      when 0 then raise ArgumentError, 'wrong number of arguments (given 0, expected 1+)'
         
     | 
| 
      
 100 
     | 
    
         
            +
                      when 1 then child_of(*path)
         
     | 
| 
      
 101 
     | 
    
         
            +
                      else child_of(path[0]).child_at(*path[1..-1])
         
     | 
| 
      
 102 
     | 
    
         
            +
                    end
         
     | 
| 
      
 103 
     | 
    
         
            +
                  else
         
     | 
| 
      
 104 
     | 
    
         
            +
                    presence.child_at(*path)
         
     | 
| 
      
 105 
     | 
    
         
            +
                  end
         
     | 
| 
      
 106 
     | 
    
         
            +
                end
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                alias [] child_at
         
     | 
| 
      
 109 
     | 
    
         
            +
                alias dig child_at
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                ##
         
     | 
| 
      
 112 
     | 
    
         
            +
                # A developer-friendly string representation of the absent tree.
         
     | 
| 
      
 113 
     | 
    
         
            +
                #
         
     | 
| 
      
 114 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
      
 115 
     | 
    
         
            +
                #
         
     | 
| 
      
 116 
     | 
    
         
            +
                def inspect
         
     | 
| 
      
 117 
     | 
    
         
            +
                  "#{absent? ? 'absent' : 'present'} child of node #{@parent_node.inspect} in #{@parent_tree.inspect}"
         
     | 
| 
      
 118 
     | 
    
         
            +
                end
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
                ##
         
     | 
| 
      
 121 
     | 
    
         
            +
                # Duplicates the resolved tree or raises an error, when unresolved.
         
     | 
| 
      
 122 
     | 
    
         
            +
                #
         
     | 
| 
      
 123 
     | 
    
         
            +
                # @return [Tree]
         
     | 
| 
      
 124 
     | 
    
         
            +
                #
         
     | 
| 
      
 125 
     | 
    
         
            +
                # @raise [TypeError] when this {Absence} is not resolved yet
         
     | 
| 
      
 126 
     | 
    
         
            +
                #
         
     | 
| 
      
 127 
     | 
    
         
            +
                def dup
         
     | 
| 
      
 128 
     | 
    
         
            +
                  presence.dup
         
     | 
| 
      
 129 
     | 
    
         
            +
                end
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
                ##
         
     | 
| 
      
 132 
     | 
    
         
            +
                # Clones the resolved tree or raises an error, when unresolved.
         
     | 
| 
      
 133 
     | 
    
         
            +
                #
         
     | 
| 
      
 134 
     | 
    
         
            +
                # @return [Tree]
         
     | 
| 
      
 135 
     | 
    
         
            +
                #
         
     | 
| 
      
 136 
     | 
    
         
            +
                # @raise [TypeError] when this {Absence} is not resolved yet
         
     | 
| 
      
 137 
     | 
    
         
            +
                #
         
     | 
| 
      
 138 
     | 
    
         
            +
                def clone
         
     | 
| 
      
 139 
     | 
    
         
            +
                  presence.clone
         
     | 
| 
      
 140 
     | 
    
         
            +
                end
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                ##
         
     | 
| 
      
 143 
     | 
    
         
            +
                # Checks if the absent tree is frozen.
         
     | 
| 
      
 144 
     | 
    
         
            +
                #
         
     | 
| 
      
 145 
     | 
    
         
            +
                # @return [Boolean]
         
     | 
| 
      
 146 
     | 
    
         
            +
                #
         
     | 
| 
      
 147 
     | 
    
         
            +
                def frozen?
         
     | 
| 
      
 148 
     | 
    
         
            +
                  if absent?
         
     | 
| 
      
 149 
     | 
    
         
            +
                    false
         
     | 
| 
      
 150 
     | 
    
         
            +
                  else
         
     | 
| 
      
 151 
     | 
    
         
            +
                    presence.frozen?
         
     | 
| 
      
 152 
     | 
    
         
            +
                  end
         
     | 
| 
      
 153 
     | 
    
         
            +
                end
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                #####################
         
     | 
| 
      
 156 
     | 
    
         
            +
                #  command methods  #
         
     | 
| 
      
 157 
     | 
    
         
            +
                #####################
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                # TODO: YARD should be informed about this method definitions.
         
     | 
| 
      
 160 
     | 
    
         
            +
                Tree.command_methods.each do |command_method|
         
     | 
| 
      
 161 
     | 
    
         
            +
                  if Tree.pure_destructive_command_methods.include?(command_method)
         
     | 
| 
      
 162 
     | 
    
         
            +
                    define_method command_method do |*args|
         
     | 
| 
      
 163 
     | 
    
         
            +
                      if absent?
         
     | 
| 
      
 164 
     | 
    
         
            +
                        self
         
     | 
| 
      
 165 
     | 
    
         
            +
                      else
         
     | 
| 
      
 166 
     | 
    
         
            +
                        presence.send(command_method, *args) # TODO: How can we hand over a possible block? With eval etc.?
         
     | 
| 
      
 167 
     | 
    
         
            +
                      end
         
     | 
| 
      
 168 
     | 
    
         
            +
                    end
         
     | 
| 
      
 169 
     | 
    
         
            +
                  else
         
     | 
| 
      
 170 
     | 
    
         
            +
                    # TODO: This method should be atomic.
         
     | 
| 
      
 171 
     | 
    
         
            +
                    define_method command_method do |*args|
         
     | 
| 
      
 172 
     | 
    
         
            +
                      create if absent?
         
     | 
| 
      
 173 
     | 
    
         
            +
                      presence.send(command_method, *args) # TODO: How can we hand over a possible block? With eval etc.?
         
     | 
| 
      
 174 
     | 
    
         
            +
                    end
         
     | 
| 
      
 175 
     | 
    
         
            +
                  end
         
     | 
| 
      
 176 
     | 
    
         
            +
                end
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
              end
         
     | 
| 
      
 179 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sycamore
         
     | 
| 
      
 2 
     | 
    
         
            +
              # raised when a value is not a valid node
         
     | 
| 
      
 3 
     | 
    
         
            +
              class InvalidNode < ArgumentError ; end
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              # raised when trying to call a additive command method of the {Nothing} tree
         
     | 
| 
      
 6 
     | 
    
         
            +
              class NothingMutation < StandardError ; end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              # raised when calling {Tree#node} or {Tree#node!} on a Tree with multiple nodes
         
     | 
| 
      
 9 
     | 
    
         
            +
              class NonUniqueNodeSet < StandardError ; end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              # raised when calling {Tree#node!} on a Tree without nodes
         
     | 
| 
      
 12 
     | 
    
         
            +
              class EmptyNodeSet < StandardError ; end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              # raised when trying to fetch the child of a leaf
         
     | 
| 
      
 15 
     | 
    
         
            +
              class ChildError < KeyError ; end
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,157 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'singleton'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sycamore
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              ##
         
     | 
| 
      
 6 
     | 
    
         
            +
              # The Nothing Tree singleton class.
         
     | 
| 
      
 7 
     | 
    
         
            +
              #
         
     | 
| 
      
 8 
     | 
    
         
            +
              # The Nothing Tree is an empty Sycamore Tree, and means "there are no nodes".
         
     | 
| 
      
 9 
     | 
    
         
            +
              #
         
     | 
| 
      
 10 
     | 
    
         
            +
              # It is immutable:
         
     | 
| 
      
 11 
     | 
    
         
            +
              # - {Tree::QUERY_METHODS Query method} calls will behave like a normal, empty Tree.
         
     | 
| 
      
 12 
     | 
    
         
            +
              # - {Tree::DESTRUCTIVE_COMMAND_METHODS Pure destructive command} calls, will be ignored, i.e. being no-ops.
         
     | 
| 
      
 13 
     | 
    
         
            +
              # - But all other {Tree::COMMAND_METHODS command} calls, will raise a {NothingMutation}.
         
     | 
| 
      
 14 
     | 
    
         
            +
              #
         
     | 
| 
      
 15 
     | 
    
         
            +
              # It is the only Tree object that will return +true+ on a {#nothing?} call.
         
     | 
| 
      
 16 
     | 
    
         
            +
              # But like {Absence}, it will return +true+ on {#absent?} and +false+ on {#existent?}.
         
     | 
| 
      
 17 
     | 
    
         
            +
              #
         
     | 
| 
      
 18 
     | 
    
         
            +
              class NothingTree < Tree
         
     | 
| 
      
 19 
     | 
    
         
            +
                include Singleton
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                ########################################################################
         
     | 
| 
      
 22 
     | 
    
         
            +
                # Absence and Nothing predicates
         
     | 
| 
      
 23 
     | 
    
         
            +
                ########################################################################
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                ##
         
     | 
| 
      
 26 
     | 
    
         
            +
                # (see Tree#nothing?)
         
     | 
| 
      
 27 
     | 
    
         
            +
                #
         
     | 
| 
      
 28 
     | 
    
         
            +
                def nothing?
         
     | 
| 
      
 29 
     | 
    
         
            +
                  true
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                ##
         
     | 
| 
      
 33 
     | 
    
         
            +
                # (see Tree#absent?)
         
     | 
| 
      
 34 
     | 
    
         
            +
                #
         
     | 
| 
      
 35 
     | 
    
         
            +
                def absent?
         
     | 
| 
      
 36 
     | 
    
         
            +
                  true
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                ########################################################################
         
     | 
| 
      
 40 
     | 
    
         
            +
                # CQS element access
         
     | 
| 
      
 41 
     | 
    
         
            +
                ########################################################################
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                # TODO: YARD should be informed about this method definitions.
         
     | 
| 
      
 44 
     | 
    
         
            +
                command_methods.each do |command_method|
         
     | 
| 
      
 45 
     | 
    
         
            +
                  define_method command_method do |*args|
         
     | 
| 
      
 46 
     | 
    
         
            +
                    raise NothingMutation, 'attempt to change the Nothing tree'
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                # TODO: YARD should be informed about this method definitions.
         
     | 
| 
      
 51 
     | 
    
         
            +
                pure_destructive_command_methods.each do |command_method|
         
     | 
| 
      
 52 
     | 
    
         
            +
                  define_method(command_method) { |*args| self }
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                def child_of(node)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  self
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                def to_native_object(sleaf_child_as: nil, **args)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  sleaf_child_as
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                ##
         
     | 
| 
      
 64 
     | 
    
         
            +
                # A string representation of the Nothing tree.
         
     | 
| 
      
 65 
     | 
    
         
            +
                #
         
     | 
| 
      
 66 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
      
 67 
     | 
    
         
            +
                #
         
     | 
| 
      
 68 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 69 
     | 
    
         
            +
                  'Tree[Nothing]'
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                ##
         
     | 
| 
      
 73 
     | 
    
         
            +
                # A developer-friendly string representation of the Nothing tree.
         
     | 
| 
      
 74 
     | 
    
         
            +
                #
         
     | 
| 
      
 75 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
      
 76 
     | 
    
         
            +
                #
         
     | 
| 
      
 77 
     | 
    
         
            +
                def inspect
         
     | 
| 
      
 78 
     | 
    
         
            +
                  '#<Sycamore::Nothing>'
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                def freeze
         
     | 
| 
      
 82 
     | 
    
         
            +
                  super
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                ########################################################################
         
     | 
| 
      
 86 
     | 
    
         
            +
                # Equality
         
     | 
| 
      
 87 
     | 
    
         
            +
                ########################################################################
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                ##
         
     | 
| 
      
 90 
     | 
    
         
            +
                # Checks if the given object is an empty tree.
         
     | 
| 
      
 91 
     | 
    
         
            +
                #
         
     | 
| 
      
 92 
     | 
    
         
            +
                # @return [Boolean]
         
     | 
| 
      
 93 
     | 
    
         
            +
                #
         
     | 
| 
      
 94 
     | 
    
         
            +
                def ==(other)
         
     | 
| 
      
 95 
     | 
    
         
            +
                  (other.is_a?(Tree) or other.is_a?(Absence)) and other.empty?
         
     | 
| 
      
 96 
     | 
    
         
            +
                end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                ########################################################################
         
     | 
| 
      
 100 
     | 
    
         
            +
                # Falsiness
         
     | 
| 
      
 101 
     | 
    
         
            +
                #
         
     | 
| 
      
 102 
     | 
    
         
            +
                # Sadly, in Ruby we can't do that match to reach this goal.
         
     | 
| 
      
 103 
     | 
    
         
            +
                #
         
     | 
| 
      
 104 
     | 
    
         
            +
                # see http://devblog.avdi.org/2011/05/30/null-objects-and-falsiness/
         
     | 
| 
      
 105 
     | 
    
         
            +
                ########################################################################
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                ##
         
     | 
| 
      
 108 
     | 
    
         
            +
                # Try to emulate a falsey value, by negating to +true+.
         
     | 
| 
      
 109 
     | 
    
         
            +
                #
         
     | 
| 
      
 110 
     | 
    
         
            +
                # @return [Boolean] +true+
         
     | 
| 
      
 111 
     | 
    
         
            +
                #
         
     | 
| 
      
 112 
     | 
    
         
            +
                # @see http://devblog.avdi.org/2011/05/30/null-objects-and-falsiness/
         
     | 
| 
      
 113 
     | 
    
         
            +
                #
         
     | 
| 
      
 114 
     | 
    
         
            +
                def !
         
     | 
| 
      
 115 
     | 
    
         
            +
                  true
         
     | 
| 
      
 116 
     | 
    
         
            +
                end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                # def nil?
         
     | 
| 
      
 119 
     | 
    
         
            +
                #   true
         
     | 
| 
      
 120 
     | 
    
         
            +
                # end
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                ########################################################################
         
     | 
| 
      
 124 
     | 
    
         
            +
                # Some helpers
         
     | 
| 
      
 125 
     | 
    
         
            +
                #
         
     | 
| 
      
 126 
     | 
    
         
            +
                # Ideally these would be implemented with Refinements, but since they
         
     | 
| 
      
 127 
     | 
    
         
            +
                # aren't available anywhere (I'm looking at you, JRuby), we have to be
         
     | 
| 
      
 128 
     | 
    
         
            +
                # content with this.
         
     | 
| 
      
 129 
     | 
    
         
            +
                #
         
     | 
| 
      
 130 
     | 
    
         
            +
                ########################################################################
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                def like?(object)
         
     | 
| 
      
 133 
     | 
    
         
            +
                  object.nil? or object.equal? self
         
     | 
| 
      
 134 
     | 
    
         
            +
                end
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                ##
         
     | 
| 
      
 137 
     | 
    
         
            +
                # @api private
         
     | 
| 
      
 138 
     | 
    
         
            +
                class NestedStringPresentation
         
     | 
| 
      
 139 
     | 
    
         
            +
                  include Singleton
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
                  def inspect
         
     | 
| 
      
 142 
     | 
    
         
            +
                    'n/a'
         
     | 
| 
      
 143 
     | 
    
         
            +
                  end
         
     | 
| 
      
 144 
     | 
    
         
            +
                end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                ##
         
     | 
| 
      
 147 
     | 
    
         
            +
                # @api private
         
     | 
| 
      
 148 
     | 
    
         
            +
                NestedString = NestedStringPresentation.instance.freeze
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
              end
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
              ############################################################################
         
     | 
| 
      
 153 
     | 
    
         
            +
              # The Nothing Tree Singleton object
         
     | 
| 
      
 154 
     | 
    
         
            +
              #
         
     | 
| 
      
 155 
     | 
    
         
            +
              Nothing = NothingTree.instance.freeze
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
            end
         
     |