Getting the full path of the function calling the constructor

ε祈祈猫儿з 提交于 2020-01-15 09:27:29

问题


I'd like the constructor of a class to automatically determine the full path to the calling function, so that that class can write a file that's guaranteed to be in the caller's directory (instead of whatever happens to be the pwd()).

So, I have the following setup:

In some_path/test.m:

function test    
    SomeClass()    
end

In some_path/some_subdir/SomeClass.m:

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

When I call test(), I get the following:

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

I expected the call to mfilename() in evalin('caller', ...) to evaluate inside test(), but apparently, that doesn't happen...

Nesting evalins doesn't seem to help:

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

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

The only way to get this to work is the far less intuitive dbstack():

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

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

What am I missing?


回答1:


It looks like you cannot use evelin for this purpose. From the documentation:

evalin('caller', expression) finds only variables in the caller's workspace; it does not find functions in the caller.

From that I read that not the full context of the calling function is recovered before evaluating the expression, only variables in the workspace of the calling function are made available.

That same documentation page also mentions this limitation:

evalin cannot be used recursively to evaluate an expression. For example, a sequence of the form evalin('caller', 'evalin(''caller'', ''x'')') doesn't work.

That is consistent with the notion that only the caller's workspace is made available, not the full context. The expression is not actually evaluated as if it were written inside the calling function.

I have repeated your experiment with a simple M-file function, just to verify this indeed is not specific to classes or constructors, but generally applies to any function, anywhere.

The dbstack option is the way to go.



来源:https://stackoverflow.com/questions/52865913/getting-the-full-path-of-the-function-calling-the-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!