2012-08-02 8 views
6

¿Es posible crear un contenedor alrededor de una función que tenga exactamente el mismo nombre que la función original?Cómo envolver una función ya existente con una nueva función del mismo nombre

Esto sería muy útil en circunstancias en las que el usuario quiere hacer algunas comprobaciones adicionales en variables de entrada antes de que se pasan a la función integrada How to interrupt MATLAB IDE when it hangs on displaying very large array?

+0

Acepto la respuesta que ha publicado en la otra pregunta (http://stackoverflow.com/questions/11779511/how-to-interrupt-matlab-ide-when-it-hangs-on-displaying-very-large- array) es bueno para esa pregunta slayton, pero la pregunta general tiene una mejor respuesta - ver abajo. – jmetz

Respuesta

11

En realidad, alternativamente, a SLAYTON de respuesta que no es necesario use openvar. Si define una función con el mismo nombre que una función de matlab, sombreará esa función (es decir, se llamará en su lugar).

Para evitar llamar recursivamente a su propia función, puede llamar a la función original desde el contenedor utilizando builtin.

p. Ej.

outputs = builtin(funcname, inputs..); 

ejemplo simple, llamado rand.m y en la ruta de MATLAB:

function out = main(varargin) 
disp('Test wrapping rand... calling rand now...'); 
out = builtin('rand', varargin{:}); 

Nota que esto sólo funciona para las funciones que se encuentran por builtin. Para aquellos que no lo son, el enfoque de slayton es probablemente necesario.

+0

, pero hay tantas funciones que no están 'integradas' y quiero envolverlas todas. –

+0

@GuntherStruyf: ¿por qué querría envolver todos ellos ... especialmente los que no están integrados? – jmetz

+0

En el trabajo, nuestras instalaciones de matlab son de solo lectura, por lo que no es posible cambiar los archivos. Y no es conveniente usar siempre myfun en lugar de diversión. especialmente cuando se trata de mejorar el comportamiento predeterminado. Aplicación en el mundo real: [problema de Daniel Kessler] (http://stackoverflow.com/questions/11779511/how-to-interrupt-matlab-ide-when-it-hangs-on-displaying-verylarge-array) –

3

Si esto es posible, pero requiere un poco de piratería informática. Requiere que copie algunos manejadores de funciones.

Usando el ejemplo proporcionado en la pregunta, mostraré cómo ajustar la función openvar en una función definida por el usuario que verifica el tamaño de la variable de entrada y luego permite al usuario cancelar cualquier operación abierta para variables demasiado grandes.

Además, esto debería funcionar cuando el usuario hace doble clic en una variable en el panel Espacio de trabajo del IDE de Matlab.

Tenemos que hacer tres cosas.

  1. obtener un identificador para el original openvar función
  2. Definir la función de contenedor que llama openvar
  3. redirigida el nombre original openvar a nuestra nueva función.

Ejemplo Función

function openVarWrapper(x, vector) 

    maxVarSize = 10000; 
    %declare the global variable 
    persistent openVarHandle; 

    %if the variable is empty then make the link to the original openvar 
    if isempty(openVarHandle) 
     openVarHandle = @openvar; 
    end 

    %no variable name passed, call was to setup connection 
    if narargin==0 
     return; 
    end 


    %get a copy of the original variable to check its size 
    tmpVar = evalin('base', x);   

    %if the variable is big and the user doesn't click yes then return 
    if prod(size(tmpVar)) > maxVarSize 
     resp = questdlg(sprintf('Variable %s is very large, open anyway?', x)); 
     if ~strcmp(resp, 'Yes') 
      return; 
     end 
    end 

    if ischar(x) && ~isempty(openVarHandle); 
     openVarHandle(x); 
    end 
end 

Una vez que esta función se define a continuación, sólo hay que ejecutar un script que

  • borra las variables con nombre openvar
  • ejecuta el script openVarWrapper para configurar la conexión
  • punto el original,210 a openVarWrapper

Ejemplo Guión:

clear openvar; 
openVarWrapper; 
openvar = @openVarWrapper; 

Finalmente cuando se desea limpiar todo simplemente puede llamar:

clear openvar; 
+0

debería ser más fácil obtener el identificador de la función sombreada, solo desde el recorrido del archivo para ser precisos. Su solución requiere alguna inicialización (cada vez que use 'borrar todo'). [Mi solución] (http://stackoverflow.com/a/11781650/1162609) requiere un cd'ing para la ruta y viceversa, pero eso es todo hackeo. Todavía espero que alguien encuentre una mejor manera: p –

Cuestiones relacionadas