gusucode.com > bigdata 工具箱 matlab源码程序 > bigdata/+matlab/+bigdata/+internal/FunctionHandle.m

    %FunctionHandle
% A class that represents a function handle that exposes information about
% the function handle to the Lazy Evaluation Framework.

% Copyright 2015 The MathWorks, Inc.

classdef (Sealed) FunctionHandle < handle & matlab.mixin.Copyable
    properties (SetAccess=immutable)
        % Whether this function handle is known not to be able to error.
        %
        % The Lazy Evaluation Framework will store extra information
        % necessary to give a nice error message.
        ErrorFree = false;
        
        % The maximum number of slices this function handle should be passed
        % in any one call.
        MaxNumSlices = Inf;
        
        % The underlying function handle (or object supporting "feval").
        Handle;
        
        % A copy of the function stack trace captured at the point of
        % FunctionHandle construction. This is to allow the right error to
        % be thrown by gather.
        ErrorStack
    end
    
    methods
        % The main constructor.
        %  functionHandle must be either a MATLAB function handle or a
        %   serializable and copyable custom class obeying the feval
        %   contract.
        %  name-value pairs are equivalent to setting the properties of this
        %  class.
        function obj = FunctionHandle(functionHandle,varargin)
            import matlab.bigdata.BigDataException;
            obj.Handle = functionHandle;
            
            p = inputParser;
            p.addParameter('ErrorFree', false, ...
                @(x)isscalar(x) && islogical(x))
            p.addParameter('ErrorStack', []);
            p.addParameter('MaxNumSlices', Inf, ...
                @(x)isscalar(x) && isnumeric(x) && (isinf(x) || mod(x,1) == 0));
            p.addParameter('NumIgnoredStackFrames', 0, ...
                @(x)isscalar(x) && isnumeric(x) && (isinf(x) || mod(x,1) == 0));
            p.parse(varargin{:});
            inputs = p.Results;
            
            obj.ErrorFree = inputs.ErrorFree;
            obj.MaxNumSlices = inputs.MaxNumSlices;
            
            if isempty(inputs.ErrorStack)
                % We add an ignored stack frame to account for the fact
                % this constructor will add one stack frame.
                inputs.ErrorStack = BigDataException.hGetStack(inputs.NumIgnoredStackFrames + 1);
            end
            obj.ErrorStack = inputs.ErrorStack;
        end
        
        % This will call feval on the held function handle, passing varargin
        % as input.
        function varargout = feval(obj, varargin)
            try
                [varargout{1:max(1, nargout)}] = feval(obj.Handle, varargin{:});
            catch err
                throwAsFunction(obj, err);
            end
        end
        
        % Helper function that throws the provided error as if it were
        % thrown from the function handle.
        function throwAsFunction(obj, err)
            import matlab.bigdata.BigDataException;
            err = BigDataException.hAttachSubmissionStack(err, obj.ErrorStack);
            
            % This error is a wrapper to separate user errors from
            % execution errors. This will be unwrapped by
            % parseExecutionError at the top level.
            iErr = MException(message('MATLAB:bigdata:array:FunctionHandleError'));
            iErr = addCause(iErr, err);
            throw(iErr);
        end
    end
    
    methods (Access = protected)
        function b = copyElement(obj)
            if isa(obj.Handle, 'function_handle')
                b = copyElement@matlab.mixin.Copyable(obj);
            else
                b = matlab.bigdata.internal.FunctionHandle(copy(obj.Handle), ...
                    'ErrorFree', obj.ErrorFree, ...
                    'ErrorStack', obj.ErrorStack, ...
                    'MaxNumSlices', obj.MaxNumSlices);
            end
        end
    end
end