docs: def roll(self, shifts=None, roll_coords=None, **shifts_kwargs):
          """Roll this dataset by an offset along one or more dimensions.
  
          Unlike shift, roll may rotate all variables, including coordinates
          if specified. The direction of rotation is consistent with
          :py:func:`numpy.roll`.
  
          Parameters
          ----------
  
          shifts : dict, optional
              A dict with keys matching dimensions and values given
              by integers to rotate each of the given dimensions. Positive
              offsets roll to the right; negative offsets roll to the left.
          roll_coords : bool
              Indicates whether to  roll the coordinates by the offset
              The current default of roll_coords (None, equivalent to True) is
              deprecated and will change to False in a future version.
              Explicitly pass roll_coords to silence the warning.
          **shifts_kwargs : {dim: offset, ...}, optional
              The keyword arguments form of ``shifts``.
              One of shifts or shifts_kwargs must be provided.
          Returns
          -------
          rolled : Dataset
              Dataset with the same coordinates and attributes but rolled
              variables.
  
          See also
          --------
          shift
  
          Examples
          --------
  
          >>> ds = xr.Dataset({'foo': ('x', list('abcde'))})
          >>> ds.roll(x=2)
          <xarray.Dataset>
          Dimensions:  (x: 5)
          Coordinates:
            * x        (x) int64 3 4 0 1 2
          Data variables:
              foo      (x) object 'd' 'e' 'a' 'b' 'c'
          """
          shifts = either_dict_or_kwargs(shifts, shifts_kwargs, 'roll')
          invalid = [k for k in shifts if k not in self.dims]
          if invalid:
              raise ValueError("dimensions %r do not exist" % invalid)
  
          if roll_coords is None:
              warnings.warn("roll_coords will be set to False in the future."
                            " Explicitly set roll_coords to silence warning.",
                            FutureWarning, stacklevel=2)
              roll_coords = True
  
          unrolled_vars = () if roll_coords else self.coords
  
          variables = OrderedDict()
          for k, v in self.variables.items():
              if k not in unrolled_vars:
                  variables[k] = v.roll(**{k: s for k, s in shifts.items()
                                           if k in v.dims})
              else:
                  variables[k] = v
  
          return self._replace_vars_and_dims(variables)