проблема при вызове функции

Поддержка
  • Какой то странный у вас получился спор.. Локальные переменные BAS видны в любых функциях в пределах одного потока, переменные js ограничены функцией в которой были объявлены.

    Вот тестовый скрипт: 2808.xml

    В нём есть функция "q" в которой объявляется переменная BAS [[NEW_VARIABLE]] и переменная js test. Обе переменные выводятся в лог для проверки:

    9478ccf7-f688-4dc1-9274-55de1b65f1aa-изображение.png

    В функции "Main" стоит вызов функции "q" и также вывод в лог обеих переменных:

    42a4507b-0817-4271-8d5c-a508bc191702-изображение.png


    В режиме "записи" логи в функции "q" и функции "Main" отработают корректно:

    f73f049e-4d28-4631-9f72-a3b1ed8d0ff3-изображение.png

    В режиме "запуска" в функции "q" сработают корректно оба лога, однако в функции "Main" корректно сработает вывод в лог только переменной BAS. Вывод переменной js вернёт ошибку:

    6c49be2e-0e19-4c3e-8ca2-1d75f4fcbbc8-изображение.png

    Однако если в переменной js убрать "var", то эта переменная также будет корректно видна в функции "Main"

    8b216017-c602-455a-a6d1-419850ef141a-изображение.png

    4e5e3a6c-cb62-4939-bcab-af2ed166f04d-изображение.png

    То есть технически переменные BAS это глобальные переменные js - [[NEW_VARIABLE]] === VAR_NEW_VARIABLE

  • @UserTrue said in проблема при вызове функции:

    Если эта функция не асинхронная

    Вероятно, у нас все таки отличия в трактовке терминов.

    Когда я пишу функция - я имею в виду функцию, которую можно создать в IDE BAS, а не какие функции у себя BAS вызывает под капотом.

    Я всегда считал, что такая функция в BAS не может быть синхронной или асинхронной, а может быть разным способ вызова функции - с ожиданием результата в том же потоке или запуске в фоне/не блокирующем основной поток режиме.

    Может быть, что способ запуска функции, меняет область видимости переменных. Этот момент мне не известен.

    Тут можно сделать вывод, что все таки, если что-то меняется, значит оно существует 😄

  • @Fox said in проблема при вызове функции:

    Какой то странный у вас получился спор..

    Изначально шла речь об отсутствии/наличии области видимости в BAS.

    Потом уже перешли в какие именно области видимости есть и как они себя ведут. И, вероятно, даже как они должны называться.

    Мое мнение - область видимости в BAS существует. Как минимум переменных.

    У @UserTrue другое мнение(как минимум было в начале разговора):

    @UserTrue said in проблема при вызове функции:

    В бас вообще нет такого понятия как область видимости

  • @sergerdn said in проблема при вызове функции:

    У @UserTrue другое мнение(как минимум было в начале разговора):

    Оно и осталось (я просто пытался разжевать все нюансы), @fox тоже самое сверху написал, что есть область видимости потока и все. Ну область видимости js, или браузера это уже немного про другое.

  • @Fox said in проблема при вызове функции:

    То есть технически переменные BAS это глобальные переменные js - [[NEW_VARIABLE]] === VAR_NEW_VARIABLE

    Спасибо, никогда не задумывался, что переменные есть двух типов:

    • [[NEW_VARIABLE]] === VAR_NEW_VARIABLE // BAS global var(global Javascript)
    • [[NEW_VARIABLE]] === NOT_WAR_JUST_PEACE_NEW_VARIABLE // not BAS, but Javascript local var
  • @sergerdn said in проблема при вызове функции:

    @Fox said in проблема при вызове функции:

    То есть технически переменные BAS это глобальные переменные js - [[NEW_VARIABLE]] === VAR_NEW_VARIABLE

    Спасибо, никогда не задумывался, что переменные есть двух типов:

    • [[NEW_VARIABLE]] === VAR_NEW_VARIABLE // BAS global var(global Javascript)
    • [[NEW_VARIABLE]] === NOT_WAR_JUST_PEACE_NEW_VARIABLE // not BAS, but Javascript local var

    [[NEW_VARIABLE]] === WAR_NEVER_CHANGES_NEW_VARIABLE

  • @Fox

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

    Чтобы случайно не изменить в функции значение переменной, которая объявлена в потоке, что ее вызвал.

    Capture.PNG
    Capture_1.PNG Capture_3.PNG

    // асинхронный вызов функции, переменная не изменена в потоке, что ее вызвал
    [844256966] [05:06:05] Thread #1 : [main thread]: main thread var value
    [828116099] [05:06:05] Thread #2 : [function param]: function param, this value should be protected from being changed within the function
    [05:06:05] Thread #2 : Thread ended with message "Ok"
    [752904000] [05:06:05] Thread #1 : [main thread]: main thread var value
    // синхронный вызов функции, переменная изменена в потоке, что ее вызвал
    [828116099] [05:06:05] Thread #1 : [function param]: function param, this value should be protected from being changed within the function
    [687643394] [05:06:05] Thread #1 : [main thread]: function param, this value should be protected from being changed within the function
    [05:06:05] Thread #1 : Thread succeeded with message "Ok"
    [05:06:05] Script finished correctly
    

    Скрипт:

    variables_test_1.xml

  • @sergerdn said in проблема при вызове функции:

    @Fox

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

    Чтобы случайно не изменить в функции значение переменной, которая объявлена в потоке, что ее вызвал.

    Скрипт:

    variables_test_1.xml

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

    Думаю нужно пояснить, что было понятно. Создайте в функции действие "Выполнить код" с кодом var VAR_NEW_VARIABLE2 = "TEST2"
    Этим самым вы создадите переменную BAS, которая будет работать во всех действиях BAS и при этом не будет видна вне функции, где её объявили (в режиме "запуска"):

    a0d2e34d-7fca-4fbc-a56e-28eca9ea886a-изображение.png

    43008880-81c2-4587-9305-714960013dfb-изображение.png

    Тестовый скрипт: 2809.xml

  • @Fox said in проблема при вызове функции:

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

    Да, есть такое.

    @Fox said in проблема при вызове функции:

    Можно с тем же успехом добавлять к названию переменной название функции, где она используется.

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

    Вероятно, это мне не актуально, так как у меня задача - вызвать функцию в изолированной среде по отношению только к основному потоку.

    @Fox said in проблема при вызове функции:

    Думаю нужно пояснить, что было понятно. Создайте в функции действие "Выполнить код" с кодом var VAR_NEW_VARIABLE2 = "TEST2"

    Хороший способ, мне нравится.

    Осталось выяснить, как реализовать изоляцию переменных внутри функции, если внутри функции вызвано что-то, что возвращает переменную BAS. Наверное, только способ называть переменную с результатом с префиксом в названии.

    И осталось выяснить как сделать так, чтобы внутри функции не было доступа к переменным, который не переданы ей в параметрах и которые объявлены в основном потоке как BAS переменные.

  • @sergerdn said in проблема при вызове функции:

    Осталось выяснить, как реализовать изоляцию переменных внутри функции, если внутри функции вызвано что-то, что возвращает переменную BAS. Наверное, только способ называть переменную с результатом с префиксом в названии.

    И осталось выяснить как сделать так, чтобы внутри функции не было доступа к переменным, который не переданы ей в параметрах и которые объявлены в основном потоке как BAS переменные.

    Странное желание, ну да ладно, если очень нужно можно использовать такой подход:

    В начале работы функции сохраняем все существующие переменные из глобального объекта в локальную переменную js. После этого очищаем глобальный объект от переменных BAS, при этом если название переменной начинается на текст "ARGUMENT" - переменную оставляем (что бы можно было в функцию передать данные. Можно придумать любой другой способ):

    var localGlobal = {};
    
    Object.keys(GLOBAL).filter(function (e) {
        return e.indexOf("VAR_") == 0;
    }).reduce(function (all, one) {
        if (one.slice(0, 12) != "VAR_ARGUMENT") {
            localGlobal[one] = eval(one);
            delete GLOBAL[one];
        }
        return all;
    }, {});
    

    В конце функции удаляем все созданные в функции переменные, кроме тех, которые начинаются на "SAVE" (что бы можно было получить результат из функции. Можно придумать любой другой способ). И восстанавливаем в глобальном объекте данные, которые сохранили ранее в переменной js:

    Object.keys(GLOBAL).filter(function (e) {
        return e.indexOf("VAR_") == 0;
    }).reduce(function (all, one) {
        if (one.slice(0, 8) != "VAR_SAVE") {
            delete GLOBAL[one];
        }
        return all;
    }, {});
    
    Object.keys(localGlobal).reduce(function (all, one) {
        GLOBAL[one] = localGlobal[one];
        return all;
    }, {});
    

    Тестовый скрипт: 2813.xml


    Я проверил работу этого способа в BAS в режиме "записи", "запуска" и в скомпилированном скрипте:

    f0d07150-7092-4a9e-b59f-d6436b06d496-изображение.png

    Но универсальность и стабильность такого способа я не гарантирую :D

  • @Fox а ещё это дополнительная нагрузка ) Лично для меня не создаёт проблем отсутствие изоляции внутри функций

  • @UserTrue said in проблема при вызове функции:

    @Fox а ещё это дополнительная нагрузка )

    Любые дополнительные вычисления являются дополнительной нагрузкой :)

    Лично для меня не создаёт проблем отсутствие изоляции внутри функций

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