1

我希望类的构造函数自动确定调用函数的完整路径,以便该类可以编写一个保证在调用者目录中的文件(而不是碰巧是pwd().

所以,我有以下设置:

some_path/test.m

function test    
    SomeClass()    
end

some_path/some_subdir/SomeClass.m

classdef SomeClass < handle    
    methods
        function obj = SomeClass()            
            evalin('caller', 'mfilename(''fullpath'')')
        end
    end    
end

当我打电话时test(),我得到以下信息:

>> test()
ans = 
    'some_path/some_subdir/SomeClass.m'  % <- ...why? 

我希望调用mfilename()inevalin('caller', ...)来评估 inside test(),但显然,这不会发生......

嵌套evalins似乎没有帮助:

...
function obj = SomeClass()            
    evalin('caller', ' evalin(''caller'', ''mfilename(''''fullpath'''')'') ')
end
...

>> test()
ans = 
    'some_path/some_subdir/SomeClass.m'

让它工作的唯一方法是不那么直观dbstack()

...
function obj = SomeClass()            
    S = dbstack(1, '-completenames');
    S(1).file            
end
...

>> test()
ans = 
    'some_path/test.m'

我错过了什么?

4

1 回答 1

1

看起来您不能evelin用于此目的。从文档中

evalin('caller', expression)仅在调用者的工作区中查找变量;它在调用者中找不到函数

从中我了解到,在评估表达式之前,调用函数的完整上下文并未恢复,只有调用函数工作区中的变量可用。

同一个文档页面也提到了这个限制:

evalin不能递归地用于计算表达式。例如,表单序列evalin('caller', 'evalin(''caller'', ''x'')')不起作用。

这与只有调用者的工作空间可用,而不是完整的上下文的概念是一致的。表达式实际上并没有被评估,就好像它是写在调用函数中一样。

我用一个简单的 M 文件函数重复了你的实验,只是为了验证这确实不是特定于类或构造函数,而是通常适用于任何地方的任何函数。

dbstack选择是要走的路。

于 2018-10-18T04:48:57.827 回答