2016-06-16 22 views
2

オーバーロードされた関数の組み込みバージョンを呼び出す前にカスタムアクションを実行するためにOctaveで組み込み関数をオーバーロードしようとしています。 MATLAB(そしておそらくOctave)では、私はbuiltin関数を使ってこれを行うことができます。Octaveで組み込み関数をオーバーロードするときの組み込み関数の不一致

典型的な関数定義は、私のカスタムアクションの実行後に/ビルトインからどこ前方の全ての入力/出力を次のようになります。今、私は、このファイル(disp.m)を配置した場合

function varargout = disp(varargin) 
    % Do a custom thing 
    fprintf('Calling overloaded disp!\n') 

    % Now call the builtin 
    [varargout{1:nargout}] = builtin('disp', varargin{:}); 
end 

を上私のパスは、dispを呼び出す関数は、内蔵のdisp関数を呼び出す前に余分な情報を出力するオーバーロードされたバージョンを実行します。

>> disp('hello world') 
Calling overloaded disp! 
hello world 

私がいる問題は、これが一部組み込み関数ではなく、すべてのために働くということです。たとえば、figureをオーバーロードしようとするとします。

function varargout = figure(varargin) 
    disp('Creating a figure!') 

    [varargout{1:nargout}] = builtin('figure', varargin{:}); 
end 

私はこれを呼び出して、builtinは再びむしろ真のビルトインよりもオーバーロードされた関数を呼び出します。

>> figure() 
Creating a figure! 
Creating a figure! 
Creating a figure! 
... 
error: max_recursion_depth exceeded 

私は、コマンドライン関数としてfigureをオーバーロードするのではなくfigure.mでそれを保存する場合は興味深いことに、それは私が期待どおりに動作します。これをデバッグすると、あなたはビルトインと同じ名前の関数を持っている場合Octaveは(明らかに)警告を発していることであった

> function varargout = figure(varargin), disp('here'), [varargout{1:nargout}] = builtin('figure', varargin{:}), endfunction 
> figure() 
here 

は今、一つのことは、私は気づきました。

警告:あなたは警告を見れば、彼らが過負荷に作品を機能と機能しないもののために、わずかに異なっている機能./disp.m影組み込み関数<は -
ワークス警告:機能./figure.m影コアライブラリ機能< - ドキュメントは、コアライブラリ関数と組み込み関数間のいずれかの区別をするようには見えません。また、この動作がで言及されていない

動作しませんbuiltinのドキュメント

この問題の原因は何ですか?この問題を回避するにはどうすればよいですか?

答えて

4

builtinは組み込み関数でのみ機能します。すでに理解しているように、問題は組み込み関数とコアライブラリ関数の区別です。

Builtin関数は、Octaveインタプリタ自体に組み込まれています。

コアライブラリ関数は、組み込み関数を含むOctaveで配布される関数ですが、これに限定されるものではありません。他のコアライブラリ関数には、Octave言語(mファイル)で記述されたすべての関数と動的にリンクされた関数(octファイル)が含まれます。これらの他の関数は、Octaveインタープリタの一部ではなく、そのディレクトリがOctaveパスに追加されているためにのみ機能します。

使用whichまたはexistは、関数が組み込みであるかどうかを調べるには:もちろん

octave> which disp 
'disp' is a built-in function from the file libinterp/corefcn/pr-output.cc 
octave> which figure 
'figure' is a function from the file /home/carandraug/.local/share/octave/4.1.0+/m/plot/util/figure.m 
octave> which audioread 
'audioread' is a function from the file /home/carandraug/.local/lib/octave/4.1.0+/oct/x86_64-pc-linux-gnu/audioread.oct 

octave> exist ("disp", "builtin") 
ans = 5 
octave> exist ("figure", "builtin") 
ans = 0 
octave> exist ("audioread", "builtin") 
ans = 0 

を、現実はということですが、機能はバージョン間の組み込みまたはMファイル関数(残るという約束はありませんこれはほとんど変わりません)。

ロジックはMatlabでは同じですが、組み込み関数のセットは異なります。

私が理解できないビットは、なぜbuiltinがオクターブプロンプトで異なる動作をするのですか?それとは別に、あなたはその後、ちょうど.octavercであなたの影に関数を定義することができます偉大な応答のための

$ tail -n 5 ~/.octaverc 
function varargout = figure (varargin) 
    mlock(); 
    disp ("here"); 
    [varargout{1:nargout}] = builtin ("figure", varargin{:}); 
endfunction 
$ octave 
octave> figure 
here 
+1

おかげでそれは非常にうまく物事をクリアして。つまり、これらのコア機能に過負荷をかけるための良い選択肢がありますか?例えば、スクリプトには 'run'があります。 – Suever

+1

@残念ながら残念ながら、私は良い選択肢がないことを知っていません。醜い回避策があります(私の編集を参照)。 – carandraug

+1

ありがとうございました!確かに醜い回避策が、私はそれが私たちが組み込み関数をオーバーロードしようとするものだと思います! – Suever

関連する問題