2010-12-03 53 views
0

我正在努力使MATLAB比它更容易使用(對我而言),而我一直想解決的問題之一是更好的類構造函數。我想有以下接口:用於MATLAB的快速和骯髒的類構造函數?

MyClass.new(some_args).method1; 

# instead of classical: 
obj = MyClass(some_args); 
obj.method1; 

我可以很容易地通過定義一個靜態方法new實現這一目標:

classdef MyClass 
    methods 
    function obj = MyClass(varargin); end 
    function method1(obj,varargin); end 
    end 

    methods (Static) 
    function obj = new(varargin); obj = MyClass(varargin{:}); end 
    end 
end 

但這需要增加這樣的方法的所有類,因此它是不是很優雅/便捷。我以爲我可以去圍繞它通過定義與下面的構造

classdef CommonClass 
    methods (Static) 
    function obj = new(varargin) 
     # getting name of the current file (Object), i.e. basename(__FILE__) 
     try clear E; E; catch E, [s, s] = fileparts(E.stack(1).file); end; 
     # creating object with name $s 
     obj = eval([s '(varargin{:})']); 
    end 
    end 
end 

classdef MyClass < CommonClass 
end 

一個共同的階級然而,這不起作用,因爲MATLAB要求從Object.mnew(),所以我得到的Object,而不是MyClass實例。

任何想法,我可以改進它?


EDIT1:

我想它也適用於其他的人裏面創建類:

classdef MyAnotherClass < CommonClass 
    methods 
    function obj = MyAnotherClass 
     child = MyClass.new; 
    end 
    end 
end 

>> MyAnotherClass.new 

回答

2

就個人而言,我不認爲這個問題與調用構造函數是,但如果您確實希望通過new呼叫,則下面的getStaticCallingClassName可能對您有用。

這裏是你如何使用它:

classdef CommonClass 
    methods (Static) 
    function obj = new(varargin) 
     %# find out which class we have to create 
     className = getStaticCallingClassName; 
     constructor = str2func(sprintf('@%s'className)); 
     %# creating object with name $s 
     obj = constructor(varargin{:}); 
    end 
    end 
end 

classdef MyClass < CommonClass 
end 

有了這個,你可以調用

obj = MyClass.new(input,arguments); 

而這裏的getStaticCallingClassName

function className = getStaticCallingClassName 
%GETSTATICCALLINGCLASSNAME finds the classname used when invoking an (inherited) static method. 
% 
% SYNOPSIS: className = getStaticCallingClassName 
% 
% INPUT none 
% 
% OUTPUT className: name of class that was used to invoke an (inherited) static method 
% 
% EXAMPLE 
% 
% Assume you define a static method in a superclass 
%  classdef super < handle 
%  methods (Static) 
%   doSomething 
%    % do something here 
%   end 
%  end 
%  end 
% 
% Also, you define two subclasses 
%  classdef sub1 < super 
%  end 
% 
%  classdef sub2 < super 
%  end 
% 
% Both subclasses inherit the static method. However, you may be 
% interested in knowing which subclass was used when calling the static 
% method. If you call the subclass programmatically, you can easily pass 
% the name of the subclass as an input argument, but you may want to be 
% able to call the method from command line without any input and still 
% know the class name. 
% getStaticCallingClassName solves this problem. Calling it in the above 
% static method 'doSomething', it returns 'sub1' if the static method was 
% invoked as sub1.doSomething. It also works if you create an instance of 
% the subclass first, and then invoke the static method from the object 
% (e.g. sc = sub1; sc.doSomething returns 'sub1' if .doSomething calls 
% getStaticCallingClassName) 
% 
% NOTE: getStaticCallingClassName reads the last workspace command from 
%   history. This is an undocumented feature. Thus, 
%   getStaticCallingClassName may not work in future releases. 
% 
% created with MATLAB ver.: 7.9.0.3470 (R2009b) on Mac OS X Version: 10.5.7 Build: 9J61 
% 
% created by: Jonas Dorn 
% DATE: 16-Jun-2009 
% 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

% get the last entry of the command line from the command history 
javaHistory=com.mathworks.mlservices.MLCommandHistoryServices.getSessionHistory; 
lastCommand = javaHistory(end).toCharArray';%'# SO formatting 
% find string before the last dot. 
tmp = regexp(lastCommand,'(?:=|\.)?(\w+)\.\w+\(?(?:.*)[;,]*\s*$','tokens'); 
try 
    className = tmp{1}{1}; 
catch me 
    className = []; 
end 
% if you assign an object, and then call the static method from the 
% instance, the above regexp returns the variable name. We can get the 
% className through getting the class of xx.empty. 
if ~isempty(className) 
    className = evalin('base',sprintf('class(%s.empty);',className)); 
end 
+0

你的方法很有趣,但沒有考慮到類可以通過`new`在其他類中創建:)這不是MATLAB風格,我知道。我只是想在我的m腳本中至少體驗一下Ruby的味道。 – 2010-12-03 22:45:00

0

我可能失去了一些東西,但

有什麼問題
method1(MyClass(some_args)) 

? (我總是使用這種模式)。

相關問題