2012-11-05 46 views
0

那麼,有沒有辦法在MATLAB中修改與當前範圍不同的範圍的導入列表?也就是說,我想能夠做到這一點:MATLAB:動態修改其他作用域的導入列表?

function import_mypackage() 
    evalin('caller', 'import mypackage.*'); 
end 

這是行不通的。調用import_mypackage時產生的錯誤,但包含在mypackage的命名空間是不是進口的,即:

function foo() 
    import_mypackage; 
    g(); % Wanted mypackage.g() but got: Undefined function or variable 'g()' 
end 

我知道,你可以修改當前範圍的或動態的導入列表或者使用eval傳遞一個變量import()。但是,我找不到任何方法來修改其他作用域的導入列表。有什麼辦法嗎?

編輯: Rody Oldenhuis在他的回答中發現了一個奇怪的函數導入行爲。他建議evalin實際上修改了調用者的導入列表,但是一旦您從import_mypackage返回,該列表就會被清除。但是,我認爲發生的事情是import表達式總是在當前的精神空間中進行評估。請參閱:

function import_mypackage() 
    evalin('caller', 'L = import(''mypackage.foo'');'); 
    foo; % It works! So the import happened in this workspace 
end 

從羅迪的反應修改:

function foo() 
    import mypackage.f; 
    import_mypackage; 
    L 
    import 
end 

會打印:

L = 

    'mypackage.foo' 


ans = 

    'mypackage.f' 

指示L定的import_mypackage範圍導入列表,但它從來沒有真正清除進口清單foo()

編輯: @RodyOldenhuis

我爲什麼要與呼叫者範圍的導入列表浪費時間的原因是,我想定義的import()一個「別名」版本。這種alias_import()將允許用戶定義包別名,以便:

​​

可等同於:

import my_toolbox_v1.* 

或郵寄至:

import my_toolbox_v2.* 

就是,我希望能夠維護工具箱的多個版本並動態控制正在導入的版本。這對於比較不同my_toolbox版本之間的結果或每當您想確保使用某個my_toolbox版本時都很有用。無論何時升級到my_toolbox的新版本,都無需轉至代碼並手動更改數百個函數中的導入指令。當然還有使這個以間接的方式,喜歡的選擇:

import(alias_import('my_toolbox')) 

使alias_import將不進行實際的進口,而只是會產生輸入到內置import。這很好,但有點冗長,這就是爲什麼我會喜歡alias_import來修改調用者的導入列表。但在看到evalin()的奇怪行爲之後,我覺得我寧願留下像現在這樣的東西。

+0

所以,我會問一個問題:爲什麼? –

+0

@RodyOldenhuis有點長,但在關鍵思想 –

+0

的問題上看到我最後一次編輯如果你有一堆目錄'+ my_package_v1','+ my_package_v2'等等,使用符號鏈接不是很容易嗎?像linux中的'ln -s + my_package_v4 + my_package',windows中的'mklink + my_package + my_package_v4' –

回答

1

看來你已經偶然發現了一些奇怪的行爲(我沒有使用工作的「bug」,直到我確信這不是Mathworks的意圖:)。

似乎

function import_mypackage() 
    evalin('caller', 'import mypackage.*'); 
end 

function foo() 
    import_mypackage; 
    g(); 
end 

不起作用,但

function import_mypackage() 
    evalin('caller', 'L = import mypackage.*'); 
end 

function foo() 
    import_mypackage; 
    L 
    import 
end 

顯示

L = 
    'mypackage.*' 

ans = 
    Empty cell array: 0-by-1 

這意味着在調用者(foo)導入列表被清除時,功能import_mypackage超出範圍。

我會說這至少是不想要的行爲,我會說這是一個bug report的情況。

作爲一個變通辦法,使用類似

function L = import_mypackage() 
    L = import('mypackage.*'); 
end 

function foo() 
    L = import_mypackage;   
    import(L{:}); 

    % do stuff with pacakge contents 
    ... 
end 

我認爲這是在evalin最好反正。

+0

有趣的是,至少這意味着'evalin'真的進入'import',因爲它有一個返回值。但是,我認爲我們不能斷定導入列表實際上已被修改,然後在退出'import_mypackage'時被清除。我會編輯我的問題以顯示我的意思。 –

+0

@ GermanGomez-Herrero:我認爲它被清除了。如果你在導入之後直接調用evalin('caller','g()')',它就可以工作。但是,當你在調用者中這樣做時,*在具有'evalin'的函數終止後... –

+0

好吧,這使得它更容易混淆。你可能是對的,但那麼爲什麼以前的調用者導入不能被清除? –