2012-11-05 2 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(). Однако я не могу найти способ изменить список импорта других областей. Там в любом случае?

EDIT: 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 

Измененный ответ Rody в:

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

напечатает:

L = 

    'mypackage.foo' 


ans = 

    'mypackage.f' 

с указанием L был установлен в списке импорта import_mypackage сферы, но что он никогда не рассеялся импортный список foo().

EDIT: @RodyOldenhuis

Причина, почему я хочу, чтобы возиться со списком импорта сферы вызывающего абонента является то, что я хочу, чтобы определить «псевдонимом» версию import(). Такой alias_import() позволит пользователю определить пакет псевдонимы, так что:

alias_import my_toolbox 

может быть эквивалентно:

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 немного длинный рассказ, но посмотрите мой последний EDIT в вопросе о ключевой идее –

+0

Если у вас есть куча каталогов '+ my_package_v1',' + my_package_v2' и т. Д., Разве не намного проще использовать символическую ссылку? Как и 'ln -s + my_package_v4 + my_package' в linux,' mklink + my_package + my_package_v4' в окнах –

ответ

1

Кажется, вы наткнулись на какое-то странное поведение (я не использую ошибку workd ", пока я не уверен, что это не то, что 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

ОК, это еще более запутывает. Возможно, вы правы, но почему, почему предыдущий импорт в вызывающем абоненте также не очищается? –

Смежные вопросы