Изменения

Материал из Chaotic Onyx
Перейти к навигацииПерейти к поиску
8315 байт добавлено ,  01:12, 13 декабря 2016
м
Откат правок ZLOFENIХ (обсуждение) к версии Michael Shepard
Строка 5: Строка 5:  
[http://www.byond.com/docs/guide/chap06.html Оригинальная 6 глава руководства на английском языке]
 
[http://www.byond.com/docs/guide/chap06.html Оригинальная 6 глава руководства на английском языке]
   −
{{Заготовка}}
+
{{Заготовка|url=http://www.byond.com/docs/guide/chap06.html}}
   −
= Глава 6: Действия Proc =
+
<b><font style="font-size:200%">Глава 6: Действия Proc</font></b>
    
''Только он потер лампу, перед ним возник джин и спросил: 'Чего ты хочешь?'.'' &mdash; Аладдин и волшебная лампа. Арабские ночи.
 
''Только он потер лампу, перед ним возник джин и спросил: 'Чего ты хочешь?'.'' &mdash; Аладдин и волшебная лампа. Арабские ночи.
Строка 13: Строка 13:  
Язык ДМ поддерживает несколько видов процедур. Первый - Verb, видимые игроком команды. Второй, не видимый игрокам, называется proc. В остальном эти процедуры можно назвать идентичными.
 
Язык ДМ поддерживает несколько видов процедур. Первый - Verb, видимые игроком команды. Второй, не видимый игрокам, называется proc. В остальном эти процедуры можно назвать идентичными.
   −
== Создание процедуры ==
+
= Создание процедуры =
    
Также процедуры можно использовать для того чтобы избежать копирования кода.
 
Также процедуры можно использовать для того чтобы избежать копирования кода.
Строка 32: Строка 32:  
Оператор ''if'', используемое в примере выше, это одна из множества процедур (инструкций), которые будут описанные в следующих частях руководства. Сейчас достаточно знать, идущий после ''if'' (с большим отступом), будет выполнен только в том случае, если условие, идущее в скобках после ''if'' - истинно.
 
Оператор ''if'', используемое в примере выше, это одна из множества процедур (инструкций), которые будут описанные в следующих частях руководства. Сейчас достаточно знать, идущий после ''if'' (с большим отступом), будет выполнен только в том случае, если условие, идущее в скобках после ''if'' - истинно.
   −
== Выполнение процедуры ==
+
= Выполнение процедуры =
    
Синтаксис выполнения процедуры схож с доступом к переменной, но, при выполнении, в скобках добавляются передаваемые в процедуру аргументы. В следующем примере, мы выполним процедуру ''HurtMe'', когда персонаж выпьет отравленное зелье.
 
Синтаксис выполнения процедуры схож с доступом к переменной, но, при выполнении, в скобках добавляются передаваемые в процедуру аргументы. В следующем примере, мы выполним процедуру ''HurtMe'', когда персонаж выпьет отравленное зелье.
Строка 49: Строка 49:  
Когда вы вызываете процедуру, компьютер выполняет каждую команду по очереди (одну за раз), начиная с верху. Некоторые операторы, как ''if'' из примера выше, могут приказать компьютеру пропустить часть команд или же наоборот выполнить часть из них несколько раз подряд. Но, за исключением этих особых случаев, все команды выполняются последовательно. Когда все команды будут выполнены, процедура будет закончена. Программисты называют это ''возвратом'', потому, что продолжится выполнение кода в той точке из которой была вызвана процедура (если таковая существует).
 
Когда вы вызываете процедуру, компьютер выполняет каждую команду по очереди (одну за раз), начиная с верху. Некоторые операторы, как ''if'' из примера выше, могут приказать компьютеру пропустить часть команд или же наоборот выполнить часть из них несколько раз подряд. Но, за исключением этих особых случаев, все команды выполняются последовательно. Когда все команды будут выполнены, процедура будет закончена. Программисты называют это ''возвратом'', потому, что продолжится выполнение кода в той точке из которой была вызвана процедура (если таковая существует).
   −
== Наследование процедур ==
+
= Наследование процедур =
    
Так же, как в ситуации с verb, процедуры proc могут быть переопределены во время наследования. Синтаксис переопределения разных видов процедур совпадает. Исходная процедура отличается от переопределений наличием слова proc. После этого она может быть переопределена, для переопределения не требуется слова ''proc''.
 
Так же, как в ситуации с verb, процедуры proc могут быть переопределены во время наследования. Синтаксис переопределения разных видов процедур совпадает. Исходная процедура отличается от переопределений наличием слова proc. После этого она может быть переопределена, для переопределения не требуется слова ''proc''.
Строка 67: Строка 67:  
Этот код позволяет DM быть уязвимым или не уязвимым по желанию. В переопределенном ''HurtMe'', первым делом происходит проверка на неуязвимость. Если DM в данный момент является уязвимым (для теста или чего-то подобного), будет вызвана родительская процедура, в данном случае, исходная версия процедуры ''HurtMe''.
 
Этот код позволяет DM быть уязвимым или не уязвимым по желанию. В переопределенном ''HurtMe'', первым делом происходит проверка на неуязвимость. Если DM в данный момент является уязвимым (для теста или чего-то подобного), будет вызвана родительская процедура, в данном случае, исходная версия процедуры ''HurtMe''.
   −
== Гибкость Аргументов ==
+
= Гибкость Аргументов =
    
Когда вы вызываете процедуру, вы можете передать в нее столько аргументов, сколько вы хотите. Всем аргументам, не переданным в процедуру при вызове, будет установлено значение равное ''null''. Гибкость позволяет вам, к примеру, добавить несколько аргументов в переопределении процедуры. Если при вызове процедуры, не будут переданы эти добавленные аргументы, их значение станет равным ''null''.
 
Когда вы вызываете процедуру, вы можете передать в нее столько аргументов, сколько вы хотите. Всем аргументам, не переданным в процедуру при вызове, будет установлено значение равное ''null''. Гибкость позволяет вам, к примеру, добавить несколько аргументов в переопределении процедуры. Если при вызове процедуры, не будут переданы эти добавленные аргументы, их значение станет равным ''null''.
Строка 79: Строка 79:  
Поскольку, мы не используем переменную [[N]] (полученный урон), мы можем вовсе не объявлять этот аргумент. Тем не менее, вызовы этой процедуры с аргументом так же будут работать. Что более важно, ''родительская процедура будет получать переданные аргументы, даже если они не были объявлены в дочерней процедуре''. Это происходит по тому, что вызов ..() без аргументов, передает в родительскую процедуру, аргументы переданные дочерней процедуре.
 
Поскольку, мы не используем переменную [[N]] (полученный урон), мы можем вовсе не объявлять этот аргумент. Тем не менее, вызовы этой процедуры с аргументом так же будут работать. Что более важно, ''родительская процедура будет получать переданные аргументы, даже если они не были объявлены в дочерней процедуре''. Это происходит по тому, что вызов ..() без аргументов, передает в родительскую процедуру, аргументы переданные дочерней процедуре.
   −
== Глобальные процедуры ==
+
= Глобальные процедуры =
    
Некоторые процедуры могут не иметь ничего общего с каким-либо объектом. Они могут быть объявлены в верхнем уровне, для повсеместного доступа к ним. Такие процедуры, обычно, выполняют различные автономные (не зависящие от объектов) расчеты.
 
Некоторые процедуры могут не иметь ничего общего с каким-либо объектом. Они могут быть объявлены в верхнем уровне, для повсеместного доступа к ним. Такие процедуры, обычно, выполняют различные автономные (не зависящие от объектов) расчеты.
Строка 85: Строка 85:  
Язык ДМ имеет множество предопределенных процедур (такие как view() или locate()), которые возвращают многократно используемые результаты. Для того, чтобы отличать их от определенных вами процедур, их часто называют инструкциями.
 
Язык ДМ имеет множество предопределенных процедур (такие как view() или locate()), которые возвращают многократно используемые результаты. Для того, чтобы отличать их от определенных вами процедур, их часто называют инструкциями.
   −
=== Объявление глобальных процедур ===
+
== Объявление глобальных процедур ==
    
Игра, в которой, к примеру, знаки зодиака играют важную роль, может иметь процедуры подобные следующей:
 
Игра, в которой, к примеру, знаки зодиака играют важную роль, может иметь процедуры подобные следующей:
Строка 107: Строка 107:  
Может потребоваться другая процедура, которая может конвертировать дни определенного месяца, в дни года. Этот код, в зависимости от даты, будет возвращать знак зодиака. Чуть позже мы рассмотрим детали реализации этого кода.
 
Может потребоваться другая процедура, которая может конвертировать дни определенного месяца, в дни года. Этот код, в зависимости от даты, будет возвращать знак зодиака. Чуть позже мы рассмотрим детали реализации этого кода.
   −
=== Вызов глобальных процедур ===
+
== Вызов глобальных процедур ==
    
Глобальные процедуры вызываются также как и любые другие. Если такая процедура возвращает значение, оно может использоваться в любом месте, где требуется выражение.
 
Глобальные процедуры вызываются также как и любые другие. Если такая процедура возвращает значение, оно может использоваться в любом месте, где требуется выражение.
Строка 124: Строка 124:  
Этот verb дает DM возможность изменять текущую дату, после чего, всем будет сообщено об изменении текущего знака зодиака. Вызов процедуры, в данном случае, просто встраивается в текст, как и любое другое выражение.  
 
Этот verb дает DM возможность изменять текущую дату, после чего, всем будет сообщено об изменении текущего знака зодиака. Вызов процедуры, в данном случае, просто встраивается в текст, как и любое другое выражение.  
   −
== Язык процедур ==
+
= Язык процедур =
    
В следующей части мы изучем предопределенные процедуры. Сейчас вы знаете, как переопределять процедуры и объявлять новые созданные вами, это позволит вам создавать объект более подходящие под ваши нужды. Но, перед тем, как заняться процедурами всерьез, вы должны выучить их язык (вы можете сделать это и в "боевых" условиях, но цена ошибки будет совсем другой). В зависимости от ваших предпочтений в языках программирования (особенно если это С или близкие к нему языки), вы можете сами выбрать то, насколько тщательно вам нужно вчитываться в следующий материал.
 
В следующей части мы изучем предопределенные процедуры. Сейчас вы знаете, как переопределять процедуры и объявлять новые созданные вами, это позволит вам создавать объект более подходящие под ваши нужды. Но, перед тем, как заняться процедурами всерьез, вы должны выучить их язык (вы можете сделать это и в "боевых" условиях, но цена ошибки будет совсем другой). В зависимости от ваших предпочтений в языках программирования (особенно если это С или близкие к нему языки), вы можете сами выбрать то, насколько тщательно вам нужно вчитываться в следующий материал.
   −
=== Операторы ===
+
== Операторы ==
    
Основной единицей процедуры является ''оператор'' - команда, которая говорит компьютеру, что нужно сделать. До этого момента вы уже видели операторы, которые присваивают переменные, выводят данные и вызывают процедуры.
 
Основной единицей процедуры является ''оператор'' - команда, которая говорит компьютеру, что нужно сделать. До этого момента вы уже видели операторы, которые присваивают переменные, выводят данные и вызывают процедуры.
Строка 141: Строка 141:  
Кроме таких простых операторов существуют составные, такие как ''if'', которые могут комбинировать несколько простых выражение в один составной. Дальше вы увидите все возможные виды операторов используемых в языке DM.
 
Кроме таких простых операторов существуют составные, такие как ''if'', которые могут комбинировать несколько простых выражение в один составной. Дальше вы увидите все возможные виды операторов используемых в языке DM.
   −
== Возврат ==
+
= Возврат =
    
Все виды процедур возвращают что-либо. Даже действия verb, что-то возвращают, но это редко используется. Если процедура завершается без возврата какого-либо явного значения, то возвращается специальное значение ''null''.
 
Все виды процедур возвращают что-либо. Даже действия verb, что-то возвращают, но это редко используется. Если процедура завершается без возврата какого-либо явного значения, то возвращается специальное значение ''null''.
   −
=== Оператор ''return'' ===
+
== Оператор ''return'' ==
    
Вы уже видели пример возврата значения с использованием выражения ''return''. Основной формат записи возврата следующий:
 
Вы уже видели пример возврата значения с использованием выражения ''return''. Основной формат записи возврата следующий:
Строка 153: Строка 153:  
Оператор return приказывает процедуре прекратить выполнение. Если возвращаемое выражение определено, оно возвращается в точку вызова процедуры. Выражение означает любой блок кода, создающий число. Это может быть константа, математическое вычисление или результат вызова другой процедуры.
 
Оператор return приказывает процедуре прекратить выполнение. Если возвращаемое выражение определено, оно возвращается в точку вызова процедуры. Выражение означает любой блок кода, создающий число. Это может быть константа, математическое вычисление или результат вызова другой процедуры.
   −
=== Переменная . (точка) ===
+
== Переменная . (точка) ==
    
Если процедура завершается без оператора ''return'', или ''return'' без следующего за ним выражения, возвращаемая величина берется из переменной . (точка). Этой переменной (как и любой другой) может быть присвоено значение. По умолчанию в . (точке) хранится ''null''. Поэтому процедура завершившаяся без явного указания возвращаемой величины возвращает ''null''.
 
Если процедура завершается без оператора ''return'', или ''return'' без следующего за ним выражения, возвращаемая величина берется из переменной . (точка). Этой переменной (как и любой другой) может быть присвоено значение. По умолчанию в . (точке) хранится ''null''. Поэтому процедура завершившаяся без явного указания возвращаемой величины возвращает ''null''.
   −
Выбор между использованием return и точкой - вопрос удобства. Но иногда, возвращаемая величина бывает рассчитанной до завершения процедуры (не все процессы завершены). Тогда удобнее будет использовать точку. Либо, если вы захотите определить другое возвращаемое по умолчанию значение.
+
Выбор между использованием return и точкой - вопрос удобства. Но иногда, возвращаемая величина бывает рассчитана до завершения процедуры (не все процессы завершены). Тогда удобнее будет использовать точку. Либо, если вы захотите определить другое возвращаемое по умолчанию значение.
    
Такое имя для переменной было выбрано для того, чтобы создать ассоциацию с текущей процедурой, по аналогии с использованием точки во множестве файловых систем для обозначения текущей директории. Это также хорошо сочетается, с двумя подряд идущими точками, для обозначения родительской процедуры (и родительской директории в файловых системах). Эта аналогия идет и дальше, вы сможете заметить это во время дискуссии о типах.
 
Такое имя для переменной было выбрано для того, чтобы создать ассоциацию с текущей процедурой, по аналогии с использованием точки во множестве файловых систем для обозначения текущей директории. Это также хорошо сочетается, с двумя подряд идущими точками, для обозначения родительской процедуры (и родительской директории в файловых системах). Эта аналогия идет и дальше, вы сможете заметить это во время дискуссии о типах.
   −
== Оператор if ==  
+
= Оператор if =
   −
Для выполнения блока кода в зависимости от состояния, используется оператор if. Основной его синтаксис:
+
Для выполнения блока кода в зависимости от состояния некого выражения, используется оператор if. Основной его синтаксис:
    
  if (expression)
 
  if (expression)
Statement1
+
Statement1
Statement2
+
Statement2
.
+
.
.
+
.
.
+
.
    
Или
 
Или
Строка 184: Строка 184:  
Операторы внутри оператора ''if'' называются его телом. Они будут выполняться, только если выражение в круглых скобках будет соответствовать истине. DM не имеет специального типа данных для определения понятий ИСТИНА и ЛОЖЬ. Вместо этого, каждый тип имеет свое представление истины, связанное с его значением. Вы скоро увидите, как это работает.
 
Операторы внутри оператора ''if'' называются его телом. Они будут выполняться, только если выражение в круглых скобках будет соответствовать истине. DM не имеет специального типа данных для определения понятий ИСТИНА и ЛОЖЬ. Вместо этого, каждый тип имеет свое представление истины, связанное с его значением. Вы скоро увидите, как это работает.
   −
=== Дополнение ''else'' ===
+
== Дополнение ''else'' ==
    
Перед тем, как начать рассматривать преобразования типов, мы должны разобраться с ''else''. Если выражение в ''if'' будет ложным, альтернативное тело оператора будет выполнено. Объединив несколько операторов, мы сможем рассмотреть все состояния условий. Основной синтаксис для это представлен ниже:
 
Перед тем, как начать рассматривать преобразования типов, мы должны разобраться с ''else''. Если выражение в ''if'' будет ложным, альтернативное тело оператора будет выполнено. Объединив несколько операторов, мы сможем рассмотреть все состояния условий. Основной синтаксис для это представлен ниже:
Строка 190: Строка 190:  
  if(expression1) Statement1
 
  if(expression1) Statement1
 
  else if(expression2) Statement2
 
  else if(expression2) Statement2
.
+
.
.
+
.
.
+
.
 
  else Statement3  
 
  else Statement3  
    
Рассматривая эту конструкцию сверху-вниз, каждое выражение будет протестировано. До тех пор, пока не будет найдена истина, соответствующие тела операций будут выполняться. Обратите внимание, что если любое условие будет истинным, то остальные операторы ''else'' будут проигнорированы. Если ни одно из условий не будет истинным последнее тело ''else'' будет выполнено.
 
Рассматривая эту конструкцию сверху-вниз, каждое выражение будет протестировано. До тех пор, пока не будет найдена истина, соответствующие тела операций будут выполняться. Обратите внимание, что если любое условие будет истинным, то остальные операторы ''else'' будут проигнорированы. Если ни одно из условий не будет истинным последнее тело ''else'' будет выполнено.
   −
== Логическое выражение ==
+
= Логическое выражение =
    
Любое выражение, стоящее в условии оператора if может быть интерпретировано как истина или ложь, программисты называют это булевым значением. В ДМ существует три случая, когда выражение интерпретируется как ложь: если выражение равно ''null'', 0 или "" (пустая сторка). Во всех других случаях выражение интерпретируется, как истина.
 
Любое выражение, стоящее в условии оператора if может быть интерпретировано как истина или ложь, программисты называют это булевым значением. В ДМ существует три случая, когда выражение интерпретируется как ложь: если выражение равно ''null'', 0 или "" (пустая сторка). Во всех других случаях выражение интерпретируется, как истина.
Строка 203: Строка 203:  
Скорее всего, вам понадобятся логические константы, обычно для этого используют числа 1 и 0. Также часто, вместо константы используют флаговую переменную (как opacity) или значение возвращаемое процедурой. Также вы можете объявить константы TRUE (ИСТИНА) и FALSE (ЛОЖЬ), если не хотите использовать их числовые эквиваленты.
 
Скорее всего, вам понадобятся логические константы, обычно для этого используют числа 1 и 0. Также часто, вместо константы используют флаговую переменную (как opacity) или значение возвращаемое процедурой. Также вы можете объявить константы TRUE (ИСТИНА) и FALSE (ЛОЖЬ), если не хотите использовать их числовые эквиваленты.
   −
== Математические операторы ==
+
== Логические операторы ==
   −
== Битовые операции ==
+
Сущестует несколько операторов для работы с логическими выражениями, все они возвращают результат в виде логического значения (0 или 1) в зависимости от аргументов этих операторов. Логические опараторы, как и другие (не логические) по большей части совпадают с таковыми в языке С (и основовашихся на нем С++ и Java).
   −
== Операторы присваивания ==
+
( Оператор это симовол, как = или !, означающий некоторое действие или вычисление. Операторы, которые ставятся перед аргументом принято называть prefix/префиксными, ставящиеся после аргумента - postfix/постфиксными. Те же операторы, с обеих сторон которых стоят аргументы, называются infix/инфиксными. )
   −
== Условный оператор ? ==
+
=== Оператор логического отрицания ! (НЕ) ===
   −
== Оператор разыменования ==
+
Оператор '''!''' вычисляет логическое отрицание аргумента следующего за ним. Проще говоря, если вырожение стоящее после '''!''' истино оператор вернел 0, если ложно оператор вернет 1.
   −
== Оператор пути ==
+
!expression
   −
== Очередность операций ==
+
Следующий пример показывает использование оператора '''!''' для изменения логического значения. Под "изменение значения", в данном случае, понимается простая замена истины на ложь и наоборот.
   −
== Операторы циклов ==
+
mob/verb/intangible()
 +
density = !density
 +
if(density) usr << "Вы материализовались."
 +
else usr << "Вы дематериализовались."
   −
== Перемещение по коду ==
+
Вот так это и работает.
   −
== Оператор выбора ==
+
=== Оператор логического умножения && (И) ===
 +
 
 +
Оператор && вычисляет логическое И от двух выражений. Если аргументы с обеих сторон от оператора будут истинны, оператор так же вернет 1, в любых других случаях оператор вернет 0. Для уменьшения числа рассчетов часто используется такая особенность этого оператора: второй аргумент не будет расчитываться, если первый аргумент ложь. Это часто применятеся, в случаях, когда второе вырожение это процедура с побочными эффектами (занимает много ресурсов, времени для выполнения), которая не должна вычисляться если определенное выражение ложно. Этот прием называется short-circuiting (укороченная оценка). Значение оператора И равно значению последнего '''вычисленного''' аргумента. Конструкция Short-circuiting была заимствована из C. Тем  не менее, в отличии от С, операторы && и || возвращают именно последний вычисленный аргумент, а не 1 или 0. Эта фича была взята из Perl.
 +
 
 +
expression1 && expression2
 +
 
 +
Пример ниже демонстрирует использование оператора &&, для того чтобы убедиться, что игрок и предмет материальны и могут взаимодействовать.
 +
 
 +
mob/verb/touch(mob/M)
 +
if(density && M.density)
 +
view() << "[usr] коснулся [M]!"
 +
else
 +
view() << "Рука [usr] прошла сквозь [M]!"
 +
 
 +
== Оператор логического сложения (ИЛИ) ==
 +
 
 +
Оператор || вычисляет логическое ИЛИ двух выражений. Если один из аргументов оператора истинен, оператор вернет 1, в любых других случаях, он вернет 0. Как и в случае с оператором &&, будет расчитанно только минимальное необходимое количество аргументов. Если первый аргумен - истина, второй аргумент не будет расчитан. Оператор вернет значение последнего расчитанного аргумента.
 +
 
 +
expression1 || expression2
 +
 
 +
Пример использования short-circuit для отображения стандартного текста, если описание предмета отсутствует.
 +
 
 +
mob/verb/look()
 +
set src in view()
 +
usr << (desc || "Ничего необычного.")
 +
 
 +
== Оператор сравнения <nowiki>==</nowiki> (эквивалентно) ==
 +
 
 +
Оператор <nowiki>==</nowiki> сравнивает два значения. Если они идентичны, оператор вернет 1, иначе 0. Стоит иметь в виду, что оператор = - это оператор присваивания, который имеет совсем другое происхождение. В отличии от языка С, ДМ не позволяет вам использовать = в выражениях (вроде if), поэтому вы можете не волноваться о том, что случайно используете не тот оператор.
 +
 
 +
Когда оператор <nowiki>==</nowiki> применяется с числами, результат это строгое сравнение чисел. В случае, когда оператор используется со ссылками, сравниваются ссылки, а не объект на который они указывают. Так что, если два объекта созданы идентичными во всех отношениях, но, это всеже разные объекты, результатом сравнения будет ЛОЖЬ. Учитывая тот факт, что одинаковые строки будут сложены в один объект для сохранения памяти, сравнение строк будет происходить путем посимвольного сравнения.
 +
 
 +
expression1 == expression2
 +
 
 +
Это пример использования оператора <nowiki>==</nowiki> для проверки, смеется ли персонаж над собой или над кем-то другим.
 +
 
 +
mob/verb/laugh(M as mob|null)
 +
  if(!M)
 +
      view() << "[usr] смеется."
 +
  else if(M == usr)
 +
      view() << "[usr] смеется над собой."
 +
  else
 +
      view() << "[usr] смеется над [M]."
 +
 
 +
= Математические операторы =
 +
 
 +
Язык ДМ поддерживает операторы для всех основных математических операций. На их основе можно воссоздать любые более сложные операции. Все рассчеты в ДМ производятся над числами с плавующей точкой, если не указано другого. Любой не числовой аргумент приравнивается к нулю
 +
 
 +
Кроме описанных выше операторов, в ДМ встроены несколько полезных математических функций (например функция эмитирующая бросок игральных костей). Более подробно они будут рассмативаться в [[DM_Guide_16|главе 16]].
 +
 
 +
= Битовые операции =
 +
 
 +
= Операторы присваивания =
 +
 
 +
= Условный оператор ? =
 +
 
 +
= Оператор разыменования =
 +
 
 +
= Оператор пути =
 +
 
 +
= Очередность операций =
 +
 
 +
= Операторы циклов =
 +
 
 +
= Перемещение по коду =
 +
 
 +
= Оператор выбора =
1059

правок

Навигация