【问题标题】:Avoid MATLAB startup warning when overloading buildin functions?重载内置函数时避免 MATLAB 启动警告?
【发布时间】:2011-09-18 12:31:19
【问题描述】:

如here 所述,我创建了自己的figure.m,它很好地重载了内置的figure 命令。现在,每当我启动 MATLAB 时,都会收到警告

警告:函数 C:\somepath\figure.m 有 与 MATLAB 内置函数同名。我们 建议您将函数重命名为 避免潜在的名称冲突。

鉴于在我的情况下这是所需的行为,有什么方法可以取消激活此警告?

你可能会说我应该以不同的方式调用我的函数而不是重载,但我确实觉得对于我的开发系统来说,这种重载是正确的方法......

更新

正如 Aabaz 所述,您可以使用全局关闭此警告

warning off MATLAB:dispatcher:nameConflict

需要在matlabrc.m的开头(在设置路径之前)。但是,我仍然对可以特别删除此错误消息以重载 figure.m(或某些自定义函数列表)而不是所有函数的解决方案感兴趣。我想我在这里问得太多了;-)?

【问题讨论】:

  • 另外,您可以在C:\somepath\private 中隐藏figure 的实现,这使其仅对somepath 中的函数可见。因此,当您处理位于 someotherpath 上的不同项目时,您可以避免名称冲突和潜在的意外行为。
  • @Jonas 很有趣,我试试看!我必须将它添加到少数不同的路径中,但这对我来说确实是一个不错的选择。
  • MATLAB 应该更好地设计我们组织路径/范围并实现某种命名空间或模块(类似于其他语言提供的)......也就是说,MATLAB 确实具有“包”功能,但它似乎是事后才添加的,以克服命名空间冲突的问题。 mathworks.com/help/techdoc/matlab_oop/brfynt_-1.html 存在其他控制范围的机制,例如:私有函数、嵌套函数和子函数。查看这个相关问题:stackoverflow.com/q/2748302

标签: matlab suppress-warnings overloading


【解决方案1】:

将包含函数重载的目录添加到搜索路径将在该目录中的函数被编辑和保存时显示警告,无论该目录是否添加到 startup.m 中。

解决这个问题的一个简单方法是将重载函数放在package 中。然后import启动时的包。无需乱用警告。

【讨论】:

    【解决方案2】:

    我还不能发表评论,所以我将在这里进一步扩展 vicvicvic 给出的答案。总体流程保持不变,但有一些进一步的微调。

    1. 将覆盖函数 figure.m 放在当前 MATLAB path 之外的文件夹中,例如/users/heidelberg/.matlab/_overload。对我来说,支持波浪号扩展,但我不会依赖它。但是,您也可以将它放在 MATLAB 启动脚本的子文件夹中(见下文)。
    2. 使用startup.m 将您的覆盖文件夹添加到路径中。为避免出现警告,请确保将其关闭,然后恢复其原始状态

      % save the current state while switching it off
      warningState = warning('off', 'MATLAB:dispatcher:nameConflict'); 
      
      addpath('/users/heidelberg/.matlab/_overload');
      
      % restore the saved state
      warning(warningState);
      
      % cleanup
      clear('warningState');
      

      这里的区别在于,如果您的管理员将警告设置为关闭,您不会意外将其重新打开。

    3. 在您的 figure 实现中,有时您可能必须调用内置版本。 vicvicvic 建议在目录中添加 cd,但也有 MATLAB 函数 builtin,它可以为您完成这项工作:

      function fig = figure(varargin)
      % overload function
      
      % call builtin figure
      varargout = cell(1, nargout);
      [varargout{:}] = builtin('figure', varargin{:});
      
      % do you magic here
      % ...
      
      end
      

      另外,使用varargout 和nargout 保留任意数量的输出参数(此时可能无关紧要,但对于其他函数或未来版本可能很重要)。


    注释

    我更喜欢的一种方法是在存储我的startup.m 文件的目录中创建一个子文件夹,例如_overload。对我来说这是/users/timm/Documents/MATLAB/_overload。要轻松添加此文件夹,请使用以下脚本:

    文件/users/timm/Documents/MATLAB/startup.m

        % extract the current directory (pwd can fail if started elsewhere)
        [currentPath, ~, ~] = fileparts(mfilename('fullpath'));
    
        % add the path, compare above
        warningState = warning('off', 'MATLAB:dispatcher:nameConflict');
        addpath([currentPath, filesep(), '_overload']);
        warning(warningState);
    
        % cleanup
        clear('currentPath', 'warningState');
    

    【讨论】:

      【解决方案3】:

      我刚刚在 MATLAB R2014b 上遇到了这个问题,我还想覆盖 figure。我认为这是最接近您更新问题的解决方案(3.5 年后......)。

      我认为使用您评论中的“肮脏”技巧实际上是最干净的,如果做得巧妙,因为它不需要您更改 matlabrc.m 并且可以仅针对您想要的功能禁止警告 strong> 覆盖内置的。

      1. 将所有默认覆盖放在一个不在您的永久 MATLAB 路径上的文件夹中。我在我的 Mac 上保留我的 ~/Documents/MATLAB/overrides。我有例如~/Documents/MATLAB/overrides/figure.m
      2. 使用 startup.m 在警告关闭的情况下将覆盖添加到您的路径,然后重新打开:
          warning off MATLAB:dispatcher:nameConflict
          addpath('/Users/victor/Documents/MATLAB/overrides');
          warning on MATLAB:dispatcher:nameConflict
      

      不确定波浪号扩展是否适用于addpath,所以我将完整路径写出来。

      这样做只会对从overrides 加载的内容有选择地抑制对我的警告。当然,您可以对文件夹命名更具选择性。这也意味着我不必更改我的 MATLAB 系统文件中的任何内容,因此它可以本地化到我的用户帐户并在升级期间保持不变(无论好坏;负责任的猴子补丁)。

      要从我的覆盖访问内置的figure,我必须暂时在那里cd(否则覆盖将简单地调用它自己)。所以figure.m 看起来像这样:

      function fig = figure(varargin)
      
      % Call original figure function
      old = pwd;
      cd(fullfile(matlabroot, 'toolbox', 'matlab', 'graphics', ''));
      fig = figure(varargin{:});
      cd(old);
      
      % ...
      % Do dirty override magic
      
      end
      

      【讨论】:

      • 用builtin调用原来的figure,见here。
      【解决方案4】:

      我似乎无法用我的 Matlab 版本 (R2008b) 复制此警告,但无论如何,如果您还没有尝试过,您应该查看函数 lastwarn 和 warning,它们允许您识别并关闭此警告。

      PS:警告最终出于某种原因出现,我能够使用 lastwarn 和 warning 将其关闭。

      >>[msgstr msgid]=lastwarn;
      >>disp(msgid);
      MATLAB:dispatcher:nameConflict
      >>warning('off',msgid);
      

      我应该补充一点,您应该在 startup 将其关闭,以便在不同的 Matlab 会话之间有效。

      【讨论】:

      • 使用 lastwarn 是个好主意,没想到。但是,由于警告是在启动期间早期生成的(当包含我的 figure.m 的目录被添加到路径中时),向 startup.m 添加警告是不够的 - 我需要将它放在全局 matlabrc.m 的开头在设置 MATLAB 路径之前。
      • 是的,你是对的,我的 Matlab 安装不会每次都显示这个警告,这很奇怪,但正如你所说,你可以在 matalbrc.m 中做到这一点。对于您的具体问题,我想您可以像重载 figure 函数一样重载 warning 函数,以便专门针对一组给定函数关闭此警告。
      • 由于msgstr 包含被重载的函数的名称,重载warning 原则上可以工作。但是,如果 MATLAB 真的 调用 重载的 warning.m 而不首先发出关于重载的警告,我会感到非常惊讶……这是一种先有鸡还是先有蛋的问题。当然,您可以使用warning off MATLAB:dispatcher:nameConflict; setmypath; warning on MATLAB:dispatcher:nameConflict 技巧来解决这个问题,但这开始变得相当肮脏;-)。
      猜你喜欢
      • 2017-02-07
      • 1970-01-01
      • 2013-01-14
      • 1970-01-01
      • 2014-01-03
      • 1970-01-01
      • 1970-01-01
      • 2022-10-06
      • 1970-01-01
      相关资源
      最近更新 更多