code: func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
  	// we use reflect.Indirect here in order to obtain the actual value from a pointer.
  	// using reflect.Indirect indiscriminately is valid here, as all runtime.Objects are supposed to be pointers.
  	// we need an actual value in order to retrieve the package path for an object.
  	if InternalObjectPreventer.IsForbidden(reflect.Indirect(reflect.ValueOf(obj)).Type().PkgPath()) {
  		return fmt.Errorf(InternalObjectPrinterErr)
  	}
  
  	if meta.IsListType(obj) {
  		// we allow unstructured lists for now because they always contain the GVK information.  We should chase down
  		// callers and stop them from passing unflattened lists
  		// TODO chase the caller that is setting this and remove it.
  		if _, ok := obj.(*unstructured.UnstructuredList); !ok {
  			return fmt.Errorf("list types are not supported by name printing: %T", obj)
  		}
  
  		items, err := meta.ExtractList(obj)
  		if err != nil {
  			return err
  		}
  		for _, obj := range items {
  			if err := p.PrintObj(obj, w); err != nil {
  				return err
  			}
  		}
  		return nil
  	}
  
  	if obj.GetObjectKind().GroupVersionKind().Empty() {
  		return fmt.Errorf("missing apiVersion or kind; try GetObjectKind().SetGroupVersionKind() if you know the type")
  	}
  
  	name := "<unknown>"
  	if acc, err := meta.Accessor(obj); err == nil {
  		if n := acc.GetName(); len(n) > 0 {
  			name = n
  		}
  	}
  
  	return printObj(w, name, p.Operation, p.ShortOutput, GetObjectGroupKind(obj))
  }
docs: // PrintObj is an implementation of ResourcePrinter.PrintObj which decodes the object
  // and print "resource/name" pair. If the object is a List, print all items in it.