code: protected function dumpProperties($abs)
      {
          $str = '';
          $propHeader = '';
          if (isset($abs['methods']['__get'])) {
              $str .= '    ✨ This object has a __get() method'."\n";
          }
          foreach ($abs['properties'] as $name => $info) {
              $vis = (array) $info['visibility'];
              foreach ($vis as $i => $v) {
                  if (\in_array($v, array('magic','magic-read','magic-write'))) {
                      $vis[$i] = '✨ '.$v;    // "sparkles" there is no magic-wand unicode char
                  } elseif ($v == 'private' && $info['inheritedFrom']) {
                      $vis[$i] = '🔒 '.$v;
                  }
              }
              $vis = \implode(' ', $vis);
              $str .= $info['isExcluded']
                  ? '    ('.$vis.' excluded) '.$name."\n"
                  : '    ('.$vis.') '.$name.' = '.$this->dump($info['value'])."\n";
          }
          $propHeader = $str
              ? 'Properties:'
              : 'Properties: none!';
          $str = '  '.$propHeader."\n".$str;
          return $str;
      }
docs: Dump object properties as text
  
  @param array $abs object abstraction
  
  @return string