【问题标题】:Getting the full path of the function calling the constructor获取调用构造函数的函数的完整路径
【发布时间】:2019-03-22 18:49:24
【问题描述】:

我希望类的构造函数自动确定调用函数的完整路径,以便该类可以编写一个保证在调用者目录中的文件(而不是碰巧是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? 

我预计在evalin('caller', ...) 中对mfilename() 的调用会在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'

我错过了什么?

【问题讨论】:

  • dbstack 有什么问题?无论如何,如果您直接将此信息传递给班级,那就更好了。这就是争论的重点。
  • 有趣!我在这里学到了一些新东西!
  • @MendiBarel dbstack 没有任何,只是我希望 evalin 表现得不同......有点上下文:我正在写类似的东西到 Python 中的pickle:一个自动且完全透明地将某些需要很长时间计算的变量缓冲到文件的类。对于这类事情,您不想打扰用户默认提供路径信息;该文件最直观的路径应该只是 默认值。 eval* 有合法用例 ????

标签: matlab oop constructor eval


【解决方案1】:

您似乎不能为此目的使用evelin。来自the documentation

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

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

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

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

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

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

dbstack 选项是可行的方法。

【讨论】:

  • 我认为文档中的那一行意味着它看不到调用者上下文的本地函数(嵌套函数、子函数等),但是像 mfilename 这样的内置函数应该仍然工作......我想你是对的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-03
  • 2017-12-12
  • 2019-02-10
  • 2011-04-16
  • 2015-02-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多