Author Topic: Ошибка обработки параметров в подпрограмме.  (Read 2395 times)

0 Members and 1 Guest are viewing this topic.

Пытливый

  • Освоившийся
  • **
  • Posts: 21
    • View Profile
Версия 4.12.001
Собственно вот такой код:
Code: [Select]
sub (SubTest1, $x, $y)
 $x = 1
 $y = 1
end_sub

sub (SubTest2, $x1, $y1)
 $x1 = 1
 $y1 = 1
end_sub

LogClear
$x = 5
$y = 5
print($x, " ", $y) // Результат 0 0
SubTest1($x, $y)
print($x, " ", $y) // Результат 5 5
$x = 5
$y = 5
SubTest2($x, $y)
print($x, " ", $y)
Как видно, совпадение имени внешней переменной с именем параметра подпрограммы приводит к обнулению внешней переменной, чего не должно быть. А вот если бы она не обнулялась, а сохраняла результат вычисления в подпрограмме это была бы очень полезная фича с передачей параметра по ссылке.

i0

  • Оплот сообщества
  • ****
  • Posts: 353
  • CMann 4.13.014 final, ie, presto, win7 x86, x64
    • View Profile
Quote from: Справка
SUB (подпрограммы)
...
После выполнения подпрограммы, сценарий продолжится с момента вызова подпрограммы. Локальные переменные подпрограммы (параметры) при этом будут уничтожены.
...
поэтому использовать только уникальные мена параметров подпрограмм. а возвращать значение можно через setvar

Пытливый

  • Освоившийся
  • **
  • Posts: 21
    • View Profile
прекращайте уже писать бред на форуме.
Если ваши ФИО БУДУТ ПОЛНОСТЬЮ СОВПАДАТЬ С параметрами вашей матери это по вашему тоже будет полезная фича?
С чего вы сделали вывод, что должно быть, а чего нет?
Совершенно нормально и самоочевидно, для нормальных людей, что название параметра подпрограммы и переменной совпадать не должны.
 Встречались до вас извращенцы, которые подпрограмму поток и точку перехода совершенно одинаково называли, но у них хоть хватало ума не заявлять, что это полезная фича.
Спокойнее и без оскорблений. Я признаю, что я не прав, если вы мне процитируете справку где сказано что ВСЕ переменные в рамках ВСЕГО скрипта должны иметь уникальные имена, включая и имена параметров в подпрограммах. Я такого не нашел. А вот то что есть в справке относительно подпрограмм и их параметрах говорит о ином:
Quote
После выполнения подпрограммы, сценарий продолжится с момента вызова подпрограммы. Локальные переменные подпрограммы (параметры) при этом будут уничтожены.
Заметьте локальные переменные и параметры подпрограммы. Это общепринятое поведение подпрограммы, подчищающей за собой. А в приведенном мной примере ничего нормального нет - это баг.

Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
В кликере все переменные глобальные. Когда доходит до end_sub переменные указанные в заголовке описания sub (SubTest1, $x, $y) будут обнулены. Зачем?... Так задумал разработчик и нет тут никаких багов.

Пытливый

  • Освоившийся
  • **
  • Posts: 21
    • View Profile
Ну тут вы правы, я в основном пишу на других языках, подчиняющихся общим стандартизированным правилам работы с переменными. Не могу даже припомнить где еще подобная реализация работы с переменными была... хотя вроде в начальных версиях фортрана, была схожая реализация. Ну да ладно, принял к сведению эту информацию. Проверил на простеньком примере, насладился результатом:
Code: [Select]
sub(Test0)
 for ($i=0, $i<5)
   print("Test0",$i)
 end_cyc
end_sub

sub(Test1)
 for ($i=0, $i<5)
Test0()
   print("Test1",$i)
 end_cyc
end_sub

LogClear()
Test1()

Остался в легком недоумении, а как народ тогда пишет многомодульные скрипты с вложениями? Пересматривать весь код, каждый раз как потребуется ввести новую переменную? 

Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Нужно учитывать эту особенность. На деле так проще, особенно для новичков которые вообще смутно понимают что такое переменные.
Code: (clickermann) [Select]
sub(Test0)
   for ($a=0, $a<5)
      print("Test0 ",$a)
   end_cyc
end_sub

sub(Test1)
   for ($b=0, $b<5)
      Test0()
      print("Test1 ",$b)
   end_cyc
end_sub

LogClear
Test1()
HALT

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Ну тут вы правы, я в основном пишу на других языках, подчиняющихся общим стандартизированным правилам работы с переменными. Не могу даже припомнить где еще подобная реализация работы с переменными была... хотя вроде в начальных версиях фортрана, была схожая реализация. Ну да ладно, принял к сведению эту информацию.
Кликер ориентирован на новичков, всё упрощённо. Поэтому все переменные глобальные. Области видимости не вводились как раз для лёгкости понимания не программистами.
У автора вечная борьба бобра с ослом простоты и функциональности.

Ну вот версия программы доросла до передачи параметров в подпрограммы... Тут было "два путя":
либо вводить разделение областей видимости переменных - глобальных/локальных/локальных потока..., что тянет создание новых операторов принудительного задания области видимости. Что усложняет "учебную курву" (learning curve), а на это автор не мох пойтить;
либо забить и оставить всё глобальным. Но тут же возникает проблема, что параметры в ПП перезатрут переменные и больше того, оставят новое значение. Автор решил их при выходе удалять.
Новичкам и так и так плохо, их переменные портятся. Явно они их не меняют присваивая значения, поэтому проблему найти не могут.

Оба варианта удалять/не удалять плохие, какой бы не выбрали. Но этот проще отловить. Вот и ты отловил. И все здесь присутствующие сразу на это напоролись. А если бы где-то молча менялись переменные, отловить было бы сложнее. Потом, просто запоминаешь, что имена параметров должны быть уникальные и всё, костыль вставлен.
Да, в других языках я такого не видел, но там нет либо одного, либо другого. А попытка скрестить слона с носорогом приводит к таким вот вопросам.


Cleoss

  • Активный участник
  • ***
  • Posts: 260
  • Автоматизируй это!
    • View Profile
Автор прав в своих поисках (и в стремлении показать всем их результаты) в том смысле, что в Кликерманне действительно есть небольшая проблемка с тем, чтоб не забыть, какие имена переменных ты уже использовал в своём скрипте. И чем больше скрипт, тем больше эта трабла. Пока в листинге экран или два, то траблы этой вроде как и нет. Но когда идёт многочасовая/многодневная правка/тестирование с допилами, ведение нескольких версий-модификаций скрипта, а попутно и редактирование других скриптов, то не мудрено и запутаться в переменных и начать повторяться. Когда создаёшь субы для других людей, то приходится тоже держать в уме, что имена для создаваемых функций и переменных лучше давать такие, которые навряд ли совпадут с такими, которые теоретически смогут создать пользователи эти подпрограмм/либ. Вечная тема поиска и отображения)