Esta página aún no se ha traducido para esta versión. Puede ver la versión más reciente de esta página en inglés.

Limpiar cuando las funciones se completan

Visión general

Una buena práctica de programación es asegurarse de que deja el entorno del programa en un estado limpio que no interfiere con ningún otro código de programa. Por ejemplo, es posible que desee

  • Cierre los archivos que haya abierto para importar o exportar.

  • Restaure la ruta.MATLAB®

  • Bloquear o desbloquear la memoria para evitar o permitir el borrado de la función o archivos MEX.MATLAB

  • Vuelva a establecer la carpeta de trabajo en su valor predeterminado si la ha cambiado.

  • Asegúrese de que las variables globales y persistentes estén en el estado correcto.

proporciona la función para este propósito.MATLABonCleanup Esta función, cuando se utiliza en cualquier programa, establece una rutina de limpieza para esa función. Cuando la función finaliza, ya sea normalmente o en caso de error o, ejecuta automáticamente la rutina de limpieza.Ctrl + CMATLAB

La siguiente instrucción establece una rutina de limpieza para el programa actualmente en ejecución:cleanupFun

cleanupObj = onCleanup(@cleanupFun);

Cuando se cierra el programa, busca las instancias de la clase y ejecuta los identificadores de función asociados.MATLABonCleanup El proceso de generar y activar la limpieza de funciones implica los siguientes pasos:

  1. Escribir una o más rutinas de limpieza para el programa en desarrollo. Supongamos por ahora que sólo se necesita una de esas rutinas.

  2. Cree un identificador de función para la rutina de limpieza.

  3. En algún momento, generalmente temprano en el código del programa, inserte una llamada a la función, pasando el identificador de función.oncleanup

  4. Cuando se ejecuta el programa, la llamada a construye un objeto de limpieza que contiene un identificador para la rutina de limpieza creada en el paso 1.onCleanup

  5. Cuando finaliza el programa, borra implícitamente todos los objetos que son variables locales.MATLAB Esto invoca el método destructor para cada objeto local en el programa, incluido el objeto de limpieza construido en el paso 4.

  6. El método destructor para este objeto invoca esta rutina si existe. Esto realiza las tareas necesarias para restaurar el entorno de programación.

Puede declarar cualquier número de rutinas de limpieza para un archivo de programa. Cada llamada a establece una rutina de limpieza independiente para cada objeto de limpieza devuelto.onCleanup

Si, por alguna razón, el objeto devuelto persiste más allá de la duración del programa, la rutina de limpieza asociada a ese objeto no se ejecutará cuando finalice la función.onCleanup En su lugar, se ejecutará siempre que se destruya el objeto (por ejemplo, desactivando la variable de objeto).

La rutina de limpieza nunca debe depender de variables que se definan fuera de esa rutina. Por ejemplo, la función anidada mostrada aquí en la izquierda se ejecuta sin error, mientras que la muy similar a la derecha falla con el error,.Función no definida o variable ' k ' Esto resulta de la dependencia de la rutina de limpieza en la variable que se define fuera de la rutina de limpieza anidada:k

function testCleanup               function testCleanup k = 3;                             k = 3; myFun                              obj = onCleanup(@myFun);     function myFun                     function myFun     fprintf('k is %d\n', k)            fprintf('k is %d\n', k)     end                                end end                                end 

Ejemplos de limpieza de un programa al salir

Ejemplo 1 — cierre los archivos abiertos al salir

cierra el archivo con el identificador cuando finaliza la función:MATLABfidopenFileSafely

function openFileSafely(fileName) fid = fopen(fileName, 'r'); c = onCleanup(@()fclose(fid));  s = fread(fid);      .      .      . end

Ejemplo 2: mantener la carpeta seleccionada

Este ejemplo conserva la carpeta actual si devuelve un error o no:functionThatMayError

function changeFolderSafely(fileName)    currentFolder = pwd;    c = onCleanup(@()cd(currentFolder));     functionThatMayError;    end   % c executes cd(currentFolder) here.

Ejemplo 3: cerrar figura y restaurar rutaMATLAB

En este ejemplo se amplía la ruta de acceso para incluir archivos en las carpetas toolbox\images y, a continuación, se muestra una figura de una de estas carpetas.MATLAB Una vez que se muestra la figura, la rutina de limpieza cierra la figura y restaura la ruta de acceso a su estado original.restore_env

function showImageOutsidePath(imageFile) fig1 = figure; imgpath = genpath([matlabroot '\toolbox\images']);  % Define the cleanup routine. cleanupObj = onCleanup(@()restore_env(fig1, imgpath));  % Modify the path to gain access to the image file,  % and display the image. addpath(imgpath); rgb = imread(imageFile); fprintf('\n   Opening the figure %s\n', imageFile); image(rgb); pause(2);     % This is the cleanup routine.    function restore_env(fighandle, newpath)    disp '   Closing the figure'    close(fighandle);    pause(2)        disp '   Restoring the path'    rmpath(newpath);    end end

Ejecute la función como se muestra aquí. Puede comprobar que la ruta de acceso se ha restaurado comparando la longitud de la ruta antes y después de ejecutar la función:

origLen = length(path);  showImageOutsidePath('greens.jpg')    Opening the figure greens.jpg    Closing the figure    Restoring the path  currLen = length(path); currLen == origLen ans =      1

Recuperar información sobre la rutina de limpieza

En el ejemplo 3 que se muestra arriba, la rutina de limpieza y los datos necesarios para llamarlo están contenidos en un identificador para una función anónima:

@()restore_env(fig1, imgpath)

Los detalles de ese manejador se encuentran entonces dentro del objeto devuelto por la función:onCleanup

cleanupObj = onCleanup(@()restore_env(fig1, imgpath));

Puede tener acceso a estos detalles mediante la propiedad del objeto de limpieza como se muestra aquí.task (Modifique la función agregando el siguiente código justo antes de la línea de comentario que dice "")showImageOutsidePath% This is the cleanup routine.

disp '   Displaying information from the function handle:' task = cleanupObj.task; fun = functions(task) wsp = fun.workspace{2,1} fprintf('\n'); pause(2); 

Ejecute la función modificada para ver la salida del comando y el contenido de una de las celdas:functionsworkspace

showImageOutsidePath('greens.jpg')  Opening the figure greens.jpg Displaying information from the function handle: fun =       function: '@()restore_env(fig1,imgpath)'          type: 'anonymous'          file: 'c:\work\g6.m'     workspace: {2x1 cell} wsp =       imageFile: 'greens.jpg'           fig1: 1        imgpath: [1x3957 char]     cleanupObj: [1x1 onCleanup]            rgb: [300x500x3 uint8]           task: @()restore_env(fig1,imgpath)  Closing the figure Restoring the path 

Uso de onCleanup versus try/catch

Otra forma de ejecutar una rutina de limpieza cuando una función finaliza inesperadamente es usar una instrucción.try, catch Sin embargo, existen limitaciones a la utilización de esta técnica. Si el usuario finaliza el programa escribiendo, sale inmediatamente del bloque y la rutina de limpieza nunca se ejecuta.Ctrl + CMATLABtry La rutina de limpieza tampoco se ejecuta cuando sale de la función normalmente.

El siguiente programa limpia si se produce un error, pero no en respuesta a:Ctrl + C

function cleanupByCatch try     pause(10); catch     disp('   Collecting information about the error')     disp('   Executing cleanup tasks') end

A diferencia de la instrucción, la función responde no sólo a una salida normal del programa y a cualquier error que pueda ser lanzado, sino también a.try/catchonCleanupCtrl + C El siguiente ejemplo reemplaza el con:try/catchonCleanup

function cleanupByFunc obj = onCleanup(@()...     disp('   Executing cleanup tasks')); pause(10);

onCleanup en scripts

no funciona en scripts como en funciones.onCleanup En las funciones, el objeto de limpieza se almacena en el espacio de trabajo de la función. Cuando la función finaliza, este espacio de trabajo se borra y ejecuta la rutina de limpieza asociada. En los scripts, el objeto de limpieza se almacena en el área de trabajo base (es decir, el espacio de trabajo utilizado en el trabajo interactivo realizado en el símbolo del sistema). Dado que salir de un script no tiene ningún efecto en el área de trabajo base, el objeto de limpieza no se borra y la rutina asociada a ese objeto no se ejecuta. Para usar este tipo de mecanismo de limpieza en un script, tendría que borrar explícitamente el objeto de la línea de comandos u otro script cuando finalice el primer script.