2015-08-27 4 views
1

Что у меня есть:«главный» функция пакета MatLab

У меня есть MatLab скрипт myscript.m, которая использует р-кодированный вспомогательные функции fcn_A.p и fcn_B.p (которые я написал и есть исходный код).

Что я хочу:

Я хотел бы распространять те, другие, как единое целое, что:

  • Основной сценарий может быть запущен через >> myscript
  • Вспомогательные функции можно получить доступ за пределами основного сценария, но все же быть защищенным.
  • >> myscript запускает скрипт - не функция. То есть переменные, которые он определяет, заданы в базовой среде matlab.
  • Все распространяется как один каталог или один файл.

Насколько это возможно, я также хотел бы избежать защиты myscript. Таким образом, его можно использовать в качестве примера использования fcn_A и fcn_B.

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

Что я пробовал:

Сложив все в тот же файл сценария не выполняет второе требование.

Выполнение этого класса (либо через файл classdef, либо в каталоге @myscript) не соответствует третьему требованию.

Выполнение этой задачи (с использованием каталога +myscript) не соответствует первому требованию.

То, что я считаю, мне нужно

Я считаю, что это можно было бы решить, если бы был способ, чтобы определить функцию «по умолчанию» пакета. Как будто содержимое +mypackage/Contents.m отображается при вводе help mypackage.

Есть ли способ сделать это?

ответ

1

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

С помощью функции вы можете поместить все использование в виде строки, а затем отобразить строку, когда myscript вызывается без аргументов или какого-либо специального аргумента, такого как «-help». Вы можете назначить выходы из myscript в базовом рабочем пространстве с помощью assignin. Например,

function myscript(varargin) 

if nargin == 0 
disp('Usage: myscript(fcn_a...'); 
return; 
end 

if strcmp(varargin{1}, 'A') 
    y = fcn_A(varargin{2:end}); 
else 
    y = fcn_B(varargin{2:end}); 
end 
assignin('base','y',y); 

end 

function y = fcn_A(varargin) 
    y = 1; 
end 
function y = fcn_B(varargin) 
    y = 2; 
end 

Теперь вы можете p-code выполнить всю эту функцию в одном файле. Вы можете сделать аналогичную настройку с классом. Там было бы лучше показать использование с помощью метода disp, а затем предоставить fcn_A и fcn_B как статические методы класса.

+0

Спасибо. «Назначение» было подсказкой, мне нужно было найти решение, которое работает так, как я хочу (почти). Что касается предложения 'if nargin == 0' вашего кода, я думаю, что использование комментария справки будет работать лучше. Затем вы можете получить описание использования через '>> help myscript'. – thomasloven

+0

Вы можете получить помощь, только если вы не p-code myscript. В противном случае вам нужно добавить дополнительный файл для получения справки. – Navan

+0

Я думал, что ты сможешь, но, как оказалось, ты абсолютно прав. Я должен был проверить свою теорию с '.m'-файлом, все еще находящимся в каталоге. Виноват. – thomasloven

1

Добавить папку, в которой содержатся ваши функции и сценарий, на путь MATLAB. Выполняет все 4 условия.

+0

За исключением, возможно, последней. Я должен был быть более ясным в вопросе, что я хотел бы избежать этого решения.Оптимально, мне нужен файл или папка, которые вы просто перемещаете в свой путь или рабочий каталог, а затем все это работает. Спасибо за предложение. – thomasloven

+0

Вы никогда ничего не говорили о том, чтобы не изменять путь в своем вопросе. С этим дополнительным требованием, я думаю, это невозможно. – Daniel

+0

@thomasloven По-моему это соответствует последнему (распространяется в одной папке). С другой стороны: лучше скопировать файлы вне MATLAB, чем ввести 'addpath ('/ this/path');' в окне Command? Это беспорядочно, создает «версии», разбросанные по всей системе для каждого пользователя, теряя пространство. Хорошо, третий аргумент сегодня не такой уж большой. –

1

Как я (и MathWorks), как правило, делают это:

  1. Убедитесь, что все соответствующие файлы в папке
  2. Zip это

Теперь вы просто 1 файл распространение, возможно даже включая документацию

Обратите внимание, что это фактически то, что делает сам MATLAB. Смотрите эту ссылку, например:

Ismemberf on matlab file exchange

+0

Спасибо. Это близко, но не совсем то, на что я надеялся. Оптимально, мне нужен файл или папка, которые вы просто перемещаете в свой путь или рабочий каталог, а затем все это работает - без распаковки или чего-то еще. Я обновил свой вопрос, чтобы скрыть это желание. – thomasloven

1

Оказалось, что все мои требования действительно могут выполняться классом с использованием assignin.

Мое решение будет выглядеть следующим образом:

файлов:

@myscript 
@myscript/myscript.m 
@myscript/fcn_A.p 
@myscript/fnc_B.p 

@ MyScript/myscript.m

classdef myscript 
    methods (Static) 
    fcn_A 
    fcn_B 
    end 
    methods 
    function self = myscript() 
     % Using a variable defined in the calling environment (if defined) 
     outside_variable = evalin('caller', 'outside_variable', NaN); 
     if isnan(outside_variable) 
     outside_variable = 'default value'; 
     end 
     ... code goes here ... 
     outside_variable = self.fcn_A(parameters, outside_variable); 
     % Putting the variable back in the calling environment (even if not defined before) 
     assignin('caller', 'outside_variable', outside_variable); 
    end 
    end 
end 

Сейчас:

  • Запуск >> myscript запускает конструктор классов и возвращает пустой объект класса, который я могу просто игнорировать.
  • myscript.fcn_A и myscript.fcn_B можно назвать, поскольку они являются функциями статического класса.
  • variable_to_save будет установлен в базовой среде, как ожидалось.
  • Перемещение каталога @myscript в путь на новом компьютере достаточно, чтобы заставить его работать.

Однако есть одна проблема. Если fcn_A или fcn_B - это класс, это не сработает, так как MATLAB не позволяет укладывать классы. Вот досада! Я не упоминал об этом в вопросе, потому что я не мог себе представить, что это могло бы изменить ситуацию ...

+0

Assignin 'caller' был бы прав, предположим, что ваш скрипт вызывается в функции. Есть некоторые недостатки, которые я вижу. 1) [matlab oop намного медленнее, чем обычные вызовы функций] (http://stackoverflow.com/questions/1693429/is-matlab-oop-slow-or-am-i-doing-something -неправильно). Когда мне нужен ООП, я принимаю это исполнение, но я бы не заплатил эту цену, просто чтобы сохранить addpath 2) assignin или eval часто обвиняют в плохой практике программирования. Он нарушает переменные области, что делает код более сложным для отладки, особенно потому, что mlint не понимает assignin и дает неправильный совет. – Daniel

+0

Хорошая точка. Обновленный ответ. 'assignin' и' eval', по моему мнению, действительно являются плохой практикой. Это решение не очень, но оно работает ... – thomasloven

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