Recursively iterate over the (dimension, stride)
        tuples specified in dim_strides, returning cloned hypercubes
        with each of the specified dimensions modified accordingly.

        For example, the following call effectively produces
        2 loops over the 'ntime' and 'nchan' dimensions
        in chunks of 10 and 4 respectively.::

            A = np.ones(size=(100, 4))
            for c in cube.cube_iter(('ntime', 10), ('nchan', 4))
                assert c.dim_extent_size('ntime', 'nchan') == (10, 4)

        Parameters
        ----------
        *dim_strides : list
            list of (dimension, stride) tuples


        Returns
        -------
            iterator
                Iterator producing hypercubes

def cube_iter(self, *dim_strides, **kwargs):
        """Recursively iterate over the (dimension, stride)
        tuples specified in dim_strides, returning cloned hypercubes
        with each of the specified dimensions modified accordingly.

        For example, the following call effectively produces
        2 loops over the 'ntime' and 'nchan' dimensions
        in chunks of 10 and 4 respectively.::

            A = np.ones(size=(100, 4))
            for c in cube.cube_iter(('ntime', 10), ('nchan', 4))
                assert c.dim_extent_size('ntime', 'nchan') == (10, 4)

        Parameters
        ----------
        *dim_strides : list
            list of (dimension, stride) tuples


        Returns
        -------
            iterator
                Iterator producing hypercubes

        """

        def _make_cube(dims, arrays, *args):
            """
            Create a hypercube given dimensions and a list of
            (dim_name, dim_slice) tuples
            """

            # Create new hypercube, registering everything in dims
            cube = HyperCube()
            cube.register_dimensions(dims)
            cube.register_arrays(arrays)

            # Now update dimensions given slice information
            for (d, (s, e)) in args:
                cube.update_dimension(name=d,
                    global_size=dims[d].global_size,
                    lower_extent=s, upper_extent=e)

            return cube

        # Extract dimension names
        dim_names = [ds[0] for ds in dim_strides]
        arrays = (hcu.reify_arrays(self.arrays(), self.dimensions(copy=False))
            if kwargs.get('arrays', False) else {})

        # Return a cube-creating generator
        return (_make_cube(self.dimensions(), arrays, *zip(dim_names, s))
            for s in self.endpoint_iter(*dim_strides, **kwargs))