Выборочное отображение скалярных значений в командном окне в режиме отладки - PullRequest
1 голос
/ 29 октября 2019

когда я запускаю команды в режиме отладки, было бы полезно (в случае присваивания переменной 1x1) отображать значение в командной строке по умолчанию, как если бы операторы не заканчивались точкой с запятой.

Существует ли способ автоматического отображения скалярных значений без удаления точек с запятой вручную?

Ответы [ 4 ]

2 голосов
/ 29 октября 2019

Как и marsei , предложенный, вы можете использовать вывод whos. Но вместо сценария вы можете написать функцию, использовать evalin и оценить ее в рабочем пространстве 'caller', которое будет рабочим пространством отладки.

function whosscalar()
    vars = evalin('caller', 'whos');
    % filter vars size 1x1 (in case of doubles, 8 bytes)
    vars([vars.bytes] ~= 8 | ~strcmp({vars.class},'double')) = [];
    % sort the scalars by name
    [~, sort_order] = sort(lower({vars.name})); % sort alphabetically 
    vars = vars(sort_order);
    % get values of the variables
    for k = 1:numel(vars)
        vars(k).value = evalin('caller', vars(k).name); 
    end
    % get max length variable name for alignment
    maxlen = max(cellfun( @length, {vars.name}));
    % print the name and value
    for k = 1:numel(vars)
        fprintf('%s\t%s\n', pad(vars(k).name, maxlen), num2str(vars(k).value))
        % instead of num2str and %s you can use %f, %g or some other formatspec. 
    end
end

Пример:

function test()

    a = 10;
    b = 20;
    c = pi;
    d = rand(100);

    fpritnf('a statement\n')

end

И в окне команд:

>> dbstop in test at 8
>> test
8   fpritnf('a statement\n')
K>> whosscalar
a   10
b   20
c   3.1416
K>> dbquit
>> 
1 голос
/ 29 октября 2019

Всякий раз, когда я вижу "это не может быть сделано", мне становится любопытно. Я думаю, что нашел обходной путь, который «настолько прост, насколько это возможно» - требующий всего одного нажатия клавиши.

Чтобы это работало, вам нужно определить новую функцию - я решил вызвать функцию vдля «значения», но вы можете взять все, что вы найдете легко (исходный код ниже). Поместите эту функцию в путь Matlab, и когда вы захотите сделать то, что вы просите, ввод 'v' в командной строке даст вам именно то, что вам нужно - выведите имя переменной и ее значение (протестировано со скалярами и строками). ). Например:

>> abc='hello world';
>> v
abc = hello world
>> abc = 123*234;
>> v
abc  =        28782

Функция может выглядеть следующим образом (очевидно, возможны многие варианты ...)

function v
    % get a trace of all the commands from the command window:
    lc = com.mathworks.mlservices.MLCommandHistoryServices.getSessionHistory;
    % the last command is the one-before-last: the last command called this
    % function!
    lastCmd = lc(end-1);

    % split the command at the '=' sign; 
    cmds = split(lastCmd,'=');

    % get the variable name:
    varName = cmds(1);

    % print the result:
    fprintf(1, '%s = ', varName(1));
    % we know the value of the variable in the "caller" space:
    disp(evalin('caller', char(varName(1))));
1 голос
/ 29 октября 2019

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

myvals = whos;
for n = 1:length(myvals)
    myvals(n).name
    eval(myvals(n).name)
end

Этот сценарий можно вызывать из приглашения K>> при отладке файлов MATLAB для получения списка значений переменных в базовой рабочей области. .

Ответ 2010 года скопирован с здесь . Я до сих пор не знаю метод для текущей версии 2019b.

0 голосов
/ 29 октября 2019

Краткий ответ: NO

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

  • Использовать Workspace Browser
  • Просто введите имя переменной в консоли
  • Выберите строкуВы хотите запустить, но пропустите ; из выбора, затем нажмите F9

Длинный ответ: Да, но вам это не понравитсяв любом случае ...

Если это действительно важно, есть способ сделать вывод скрипта / функции в консоли при запуске построчно (или кодировать раздел за разделом), но это довольнозамысловатый и требует от вас кодирования такого поведения (это не вариант, предлагаемый MATLAB).

Для этого, когда оно присваивает значение, ваш код должен знать, как оно было вызвано. Это делается путем извлечения трассировки стека. Трассировка стека перечислит все дерево вызовов функций, поэтому:

  • , если текущий код был вызван из другой функции => не отображать вывод в консоли
  • , если стекдерево пусто, код был выполнен вручную => отобразить вывод в консоли.

Это звучит относительно легко, но реализовать во всех ваших скриптах или функциях будет действительно утомительно. Рассмотрим следующий сценарий: stackTestScript.m

%% stack test script
a = 3 ;

%%
s = dbstack ;
if isempty(s)
    b = a.^2
else
    b = a.^2 ;
end

Этот сценарий сохранен и в пути. Если я просто наберу stackTestScript в консоли, скрипт выполнится, в консоли ничего не отобразится, но я смогу увидеть в своем Workspace Browser ( действительно хороший инструмент, вы должны его использовать) что теперь у меня есть переменная b, имеющая значение 9 => success.

Теперь, если я выполняю скрипт секция за секцией, когда выполняется вторая секция кода, консольотображает:

b =
     9

Это поведение будет работать точно так же в function. Там нет никакой разницы.

Как видите, он дает желаемый результат, но какой ценой. Вы должны повторить каждое присвоение переменной дважды (одно с ; и одно без) и заключить это в структуру if/else с несколькими строками кода. Огромные усилия для одного задания, и вам придется повторить это для каждой интересующей переменной.

Теперь, если вы готовы потерять немного информации, есть способ сделать это менее утомительным. Сделайте пользовательскую функцию для назначения и выполните проверку стека изнутри. Рассмотрим следующую функцию dbAssign.m:

function [ value_just_assigned ] = dbAssign( in )
    s = dbstack ;
    if numel(s)<=1
        value_just_assigned = in 
    else
        value_just_assigned = in ;
    end

Вооружившись этим, теперь вы можете изменить исходный скрипт stackTestScript.m на:

%% stack test script
a = 3 ;

%%
b = dbAssign( a.^2 ) ;

pfewww, по крайней мере теперь каждое назначение можетпомещается в одну строку (хотя с нетрадиционным синтаксисом). Это прекрасно работает при вызове из другой функции (без отображения), но если мы будем запускать построчно, после выполнения второго блока мы теперь получим в консоли:

value_just_assigned =
     9

Вы не сможетезнать имя переменной, которая была назначена, она всегда будет отображаться как value_just_assigned (или какое бы имя выходного файла вы не указали в dbAssign.m). Поэтому, если у вас есть несколько инструкций присваивания, вам придется следить за тем, какую строку вы только что выполнили.

Был бы (грязный) способ получить назначенное имя переменной, но только в том случае, если она вызываетсяпо функции, а не в том случае, если вы хотите (код выполняется строка за строкой), так что это нам здесь не поможет.


Итог, текущие инструменты (Workspace Browser да, опять же) гораздо удобнее, и я бы не стал постоянно использовать какой-либо код, упомянутый выше (кроме как для эксперимента).

Был бы какой-то способ продвинуть этот хак дальше,но они требуют использования семейства функций eval, которые я, конечно, не буду здесь продвигать (приведенный выше код уже является серьезным хаком, я бы не хотел, чтобы другой (худший) слой сверху.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...