Получение полного пути к функции, вызывающей конструктор - PullRequest
0 голосов
/ 18 октября 2018

Мне бы хотелось, чтобы конструктор класса автоматически определял полный путь к вызывающей функции, чтобы этот класс мог записать файл, который гарантированно будет находиться в каталоге вызывающей стороны (вместо того, что случается с 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() в evalin('caller', ...) оценит внутри 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'

Что мне не хватает?

1 Ответ

0 голосов
/ 18 октября 2018

Похоже, вы не можете использовать evelin для этой цели.Из документация :

evalin('caller', expression) находит только переменных в рабочей области вызывающего;он не находит функции в вызывающей стороне.

Из этого я прочитал, что не весь контекст вызывающей функции восстанавливается до вычисления выражения, только переменные в рабочей областивызывающая функция доступна.

На этой же странице документации также упоминается это ограничение:

evalin нельзя использовать рекурсивно для вычисления выражения.Например, последовательность вида evalin('caller', 'evalin(''caller'', ''x'')') не работает.

Это согласуется с представлением о том, что доступна только рабочая область вызывающей стороны, а не полный контекст.Выражение фактически не оценивается так, как если бы оно было записано внутри вызывающей функции.

Я повторил ваш эксперимент с простой функцией M-файла, просто чтобы убедиться, что это действительно не относится к классам или конструкторам, но обычноприменяется к любой функции, где угодно.

Опция dbstack - это путь.

...