Библиотека сайта rus-linux.net
Ошибка базы данных: Table 'a111530_forumnew.rlf1_users' doesn't exist
Языки сценариев: что это такое и для чего они нужны?
Оригинал: Scripting Languages: What and Why?
Автор: Juliet Kemp
Дата публикации: 14 декабря 2016 г.
Перевод: А.Панин
Дата перевода: 8 января 2017 г.
Для чего компилировать исходный код программы, если от нее не требуется высокой производительности?
Для чего это нужно?
- Вы сможете выбрать язык программирования, лучше всего подходящий для ваших целей.
- Вы научитесь создавать асинхронные сценарии для последующего использования на сетевых ресурсах.
Языки сценариев на сегодняшний день используются чуть ли не повсеместно; но чем они являются на самом деле? По сути, язык сценариев отличается от традиционного языка программирования не функциями, а назначением: он предназначен для создания и последующего исполнения сценариев (или, грубо говоря, автоматизированного исполнения последовательностей команд).
Это означает, что типичный язык сценариев является интерпретируемым, а не компилируемым, а также позволяет использовать динамическую типизацию. (Теоретически вы также можете написать "сценарий" на языке программирования другого типа, но при этом такой язык, как Java, окажется не лучшим вариантом для выполнения данной работы.) Приведенная выше классификация языков программирования на основе их областей применения подразумевает, что граница раздела между языками сценариев и языками программирования общего назначения является немного размытой. Под "сценарием" обычно понимается единый фрагмент кода, который исполняется от начала до конца, но такие языки сценариев общего назначения высокого уровня, как Perl, Python и Ruby могут использоваться для разработки "сценариев", состоящих из тысяч строк кода и множества компонентов.
Как правило, языки сценариев проектируются с целью достижения максимальной скорости изучения и разработки. Однако, ввиду того, что данные языки являются интерпретируемыми (это утверждение справедливо в большинстве случаев, но имеются и исключения, такие, как язык Ruby, который может быть как интерпретируемым, так и компилируемым в зависимости от реализации), созданные с их использованием сценарии зачастую исполняются медленнее, чем бинарные программы, созданные с использованием компилируемых языков программирования. Постоянно растущая популярность этих языков напрямую связана с постоянным повышением производительности доступного аппаратного обеспечения. Чем быстрее работает компьютер, тем меньшее значение будет иметь разница в скорости между интерпретируемыми и компилируемыми программами; при этом решающее значение будет иметь скорость процесса разработки. Пропуск этапа компиляции значительно упрощает цикл разработки и отлично сочетается с такими современными практиками программирования, как экстремальное программирования. При этом по мере увеличения объема кода и сложности программного обеспечения может появиться смысл в возврате к использованию компилируемого языка программирования.
На сегодняшний день в мире языков сценариев доминируют высокоуровневые динамические языки программирования общего назначения, обычно рассматриваемые как "связующие" языки, объединяющие несколько программных компонентов. Другие языки сценариев, такие, как Sed, Awk или (являющийся более современным) JavaScript являются предметно-ориентированными. JavaScript является встраиваемым языком, который используется исключительно в рамках определенных приложений или наборов приложений. Emacs Lisp является еще одним специфичным для приложения языком сценариев, при этом во многих играх используются собственные реализации языков сценариев или особые диалекты существующих языков сценариев. Наконец, языки для управления задачами и языки командных интерпретаторов, таких, как Bash, являются еще одной формой языков сценариев и обычно используются в качестве "связующих" языков для интерпретаторов и утилит с интерфейсом командной строки.
История развития языков сценариев
Первые мэйнфреймы не поддерживали широкого спектра механизмов (или вообще не поддерживали механизмов) взаимодействия с пользователями; вместо них использовались очереди задач. Для упрощения процесса обработки задач были разработаны различные языки, включая язык Job Control Language, созданный специалистами компании IBM.
В 1960 году на смену языкам обработки задач пришли интерактивные командные оболочки и сценарии, позволяющие автоматизировать запуск программ. Они позволили задействовать дополнительные удобные функции благодаря работе множества программистов. Язык TRAC, созданный Калвином Муерсом, принес идеи подстановки команд в сценариях, а также использования вывода этих команд в рамках этих же сценариев - этот механизм напоминает оператор обратных кавычек в современных командных оболочках.
Стьюарт Мадник из MIT разработал язык сценариев CMS EXEC (в оригинале имевший имя COMMAND) для IBM VM/CMS OS в конце 60-х годов прошлого века. Он поддерживал управляющие выражения различных типов (включая условные инструкции и циклы), а также несколько встроенных функций. Очевидно, что именно с данного момента началось развитие современных языков сценариев.
Множество Мандельброта
Множество Мандельброта определено на плоскости комплексных чисел (представленной, как система координат (x,y)). Для каждого комплексного числа c должна существовать ограниченная последовательность:
zk+1 = zk2 + c
Если для числа c последовательность является ограниченной, это число находится в множестве Мандельброта. Если же последовательность является неограниченной, число c не находится в множестве Мандельброта.
При расчете мы будем осуществлять 50-кратную итерацию в рамках последовательности и в том случае, если значение zk + 1
будет покидать окружность радиусом 2 вокруг значения c
, мы будем делать вывод о том, что число c не находится в рассматриваемом множестве.
Наша система координат будет иметь ось x с координатами от -2 до 1 и ось y с координатами от -1 до 1. Мы будем отображать ее с помощью ASCII-символов начиная с верхнего левого угла (с координатами x=-2, y=1), причем вывод результатов будет заключаться в последовательном выводе строк по оси y. Каждый ASCII-символ (пробел или *) будет соответствовать сдвигу на 0.05 по оси координат. Вы сможете самостоятельно заменить жестко заданные значения для того, чтобы оценить полученные в результате изменения или добавить поддержку цветов для того, чтобы визуально усложнить вывод.
С помощью соответствующей программы вы можете самостоятельно сгенерировать графическое представление рассматриваемого множества и увеличить его масштаб для более подробного рассмотрения особенностей полученного фрактала.
Perl
Ларри Уолл выпустил версию 1.0 интерпретатора языка Perl в 1987 году. Его цель заключалась в создании языка сценариев общего назначения для Unix, максимально упрощающего процесс обработки отчетов. Повышение производительности доступного аппаратного обеспечения ознаменовало эпоху, в которой эффективность практик программирования приобрела большую важность по сравнению с производительностью кода, а Ларри Уолл, в свою очередь, не преминул подтвердить данный тезис на практике. Предшественниками языка Perl были языки Awk (представленный в 1977 году) и Unix shell sh (представленный в 1978 году), причем сам этот язык опередил появление ядра Linux (первая версия которого была представлена в 1991 году) на несколько лет. (Обратитесь к странице, расположенной по адресу
Версии 2 (1988 года) и 3 (1989 года) интерпретатора Perl были представлены общественности спустя непродолжительное время. Версия 4 интерпретатора Perl была выпущена лишь для того, чтобы четко увязать ее с каноническим руководством по программированию на языке Perl, изданным под названием "Программирование на Perl" (в оригинале "Programming Perl" или "Camel Book").
Код версии 5 интерпретатора Perl (1994 года) был частично переписан и позволял использовать ряд новых сущностей, включая объекты и модули. Поддержка этих сущностей, в свою очередь, ознаменовала расцвет ресурса CPAN (Comprehensive Perl Archive Network), являющегося репозиторием компонентов интерпретатора и модулей Perl, в 1995 году. Хотя CPAN и является крайне полезным ресурсом, на нем несложно потеряться; на момент написания статьи на нем было опубликовано 157742 модуля, причем качество этих модулей значительно отличается и в некоторых случаях на нем крайне сложно найти модуль высокого качества для выполнения той или иной задачи. (Проект MetaCPAN и модуль Task::Kensho от Enlightened Perl Organisation были созданы специально для решения описанной проблемы.)
Версия 6 интерпретатора Perl находится в стадии активной разработки и на сегодняшний день рассматривается разработчиками как отдельная реализация языка программирования; обратная совместимость с классическим языком Perl не является их целью, тем не менее, в будущем Perl 6 должен стать "эталонной реализацией языка Perl". Изменения в язык вносятся главным образом с целью упорядочивания его синтаксиса. Разработка данной версии интерпретатора началась в 2000 году и продолжается до сих пор.
Язык Perl все еще активно используется и, без сомнения, будет актуален в течение долгого времени. Однако, в последнее время он утратил свою былую популярность, особенно в рамках новых проектов. "Всегда существует более одного способа выполнения конкретной задачи" - девиз разработчиков языка Perl, доказывающий его беспрецедентную гибкость, которая является как его главным достоинством, так и его главным недостатком.
Совет: несмотря на то, что языки Sed и Awk являются предметно-ориентированными, вы сможете найти и код общего назначения на этих языках, обратившись к веб-сайту Rosetta Code!
Дополнительная информация: неофициальной расшифровкой названия языка Perl является "Practical Extraction and Reporting Language" ("практический язык для извлечения данных и составления отчетов"), но Ларри Уолл предпочитает использовать свой шуточный вариант "Pathalogically Eclectic Rubbish Lister" ("паталогически эклектичный перечислитель мусора").
Код на Perl
Интерпретатор Perl поставляется в составе практически всех современных дистрибутивов Linux; если он не установлен в вашей системе, вам придется воспользоваться менеджером пакетов дистрибутива для его установки. А это код программы "Hello World":
#!/usr/bin/perl -w print "Hello World\n";
Последовательность символов #!
является последовательностью шебанг, сообщающей системе о том, что остальную часть строки следует считать путем к исполняемому файлу интерпретатора, причем при запуске интерпретатора нужно передать ему путь к открытому файлу сценария. Таким образом, при запуске сценария hello.pl
первая его строка сообщает системе о том, что следует исполнить бинарный файл /usr/bin/perl
и передать ему путь к файлу сценария hello.pl
для интерпретации. Интерпретаторы языков сценариев обычно игнорируют последовательность символов шебанг либо из-за того, что символ #
является индикатором строки комментария, либо из-за того, что эта последовательность символов известна интерпретатору и игнорируется им.
Параметр -w
позволяет активировать механизм вывода сообщений об ошибках, который является весьма полезным на практике. (Вы также можете добавить в свой сценарий строку use strict;
сразу же после первой строки для того, чтобы заранее получать информацию об определенных ошибках времени компиляции и исполнения.) Вы наверняка заметили, что все инструкции языка Perl заканчиваются символом ;. Теперь следует сделать файл сценария исполняемым и запустить его с помощью команды ./hello.pl
.
А это гораздо более интересный код, отображающий множество Мандельброта в окне вашего эмулятора терминала:
Как видно из кода, функции/подпрограммы идентифицируются с помощью ключевого слова sub
. Параметры передаются в них в виде списков и могут извлекаться по одному путем специальной операции сдвига. При этом параметры не должны каким-либо образом описываться рядом с именами функций. Наша подпрограмма возвращает ненулевое значение в том случае, если значение не входит в множество Мандельброта и нулевое значение в противном случае.
Циклы for
используют по три значения: for (начальное_значение; конечное_значение; приращение) {..}
. Вы можете как увеличивать, так и уменьшать значение переменной в рамках цикла for
, кроме того, никто не запрещает вам использовать вложенные циклы таким же образом, как в примере выше.
Использованный в коде выше оператор ?
является сокращенным вариантом условной инструкции it-then-else. В том случае, если функция возвращает истинное логическое значение true
(обозначающее, что значение находится за пределами множества), мы выводим символ пробела; в противном случае мы выводим символ звездочки.
Исполнение сценария на языке Perl
Python
Язык Python является чуть ли не ровесником языка Perl; Гвидо ван Россум (великодушный пожизненный диктатор сообщества разработчиков Python) начал работу над реализацией первой версии его интерпретатора под номером 0.9.0 в 1989 году и выпустил ее в 1991 году. На тот момент интерпретатор уже позволял использовать классы и механизм их наследования, а также функции, основные типы данных и модули. В 1994 году наконец была выпущена версия 1.0 данного интерпретатора, поддерживающая функции lambda
, map,
filter
и reduce
, хорошо знакомые разработчикам, использующим язык Lisp. Изначально логичный и простой синтаксис языка Python прорабатывался главным образом с целью привлечения к разработке программных продуктов не-программистов; на сегодняшний день он все еще дорабатывается с целью достижения максимальной логичности и простоты синтаксических конструкций, но не-программисты уже не рассматриваются в качестве его целевой аудитории.
Функции языка Python могут свободно расширяться, причем модули могут разрабатываться как с использованием языка Python, так и с использованием языка C; это означает, что коллеги Гвидо ван Россума, привыкшие к языку C, могли начинать работу с новым для них языком Python без дополнительной подготовки. Одна из целей автора языка заключалась в создании своеобразного моста между языком командной оболочки и языком C; другими словами, он создавал второй язык для разработчиков, постоянно использующих языки C и C++, который мог бы применяться в тех случаях, когда использование языка C или C++ нецелесообразно. В основу языка Python были положены идеи, заимствованные из таких языков программирования, как ABC (язык программирования для не-программистов), C, Bash, Lisp, Perl и Java.
В версию интерпретатора 2.0, выпущенную в 2000 году, была добавлена абстракция списков, предназначенная для упрощения методики создания и обработки различных списков и основывающаяся на идее, заимствованной из функциональных языков программирования. Версия интерпретатора 3.0 была выпущена в 2008 году и содержала огромное количество изменений, направленных главным образом на сокращение избыточности, накопленной в процессе разработки предыдущих версий интерпретатора Python (с неизбежным нарушением обратной совместимости). В отличие от подхода разработчиков интерпретатора Perl, у разработчиков версии 3.0 интерпретатора Python был следующий девиз: "Должен существовать один, а еще лучше единственный очевидный способ выполнения конкретной задачи". При этом была сохранена мультипарадигменность, присущая языкам сценариев общего назначения; в результате вы можете использовать язык Python для написания объектно-ориентированного, структурного, функционального кода и так далее. Подобная гибкость хотя и является полезной, но нередко также становится причиной возникновения сложностей при разборе кода других людей особенно начинающими разработчиками.
Код на языке Python является компактным (вам придется написать меньше строк кода для выполнения той же работы по сравнению, к примеру, с языком Java) и хорошо читаемым, исполняется достаточно быстро, позволяет вести быструю разработку программ (как и все остальные языки сценариев), позволяет применять приемы объектно-ориентированного программирования и может ложиться в основу программных решений для широкого спектра областей применения. Однако, он все же исполняется медленнее, чем машинный код, полученный в результате использования компилируемых языков программирования, и, несмотря на благотворное воздействие некоторых оптимизаций, не используется в веб-приложениях на стороне клиента. Появление огромного количества библиотек для данного языка в последние годы значительно повысило его популярность; он всегда был доступен для начинающих разработчиков, а сейчас стал актуален и для профессионалов.
Прекрасное интервью Гвидо ван Россума об истоках языка программирования Python доступно по ссылке
Код на языке Python
В вашей системе наверняка также установлен интерпретатор языка Python (если это не так, вам следует воспользоваться менеджером пакетов вашего дистрибутива для его установки). А это код программы "Hello World":
#!/usr/bin/python print "Hello World"
Вам не придется использовать последовательность символов, соответствующую символу перехода на новую строку, в конце выводимой строки. Также вы не должны использовать символ точки с запятой для завершения инструкции, ведь интерпретатор Python использует в качестве его эквивалента символ пробела.
А это код на языке Python, визуализирующий множество Мандельброта:
Как и в случае языка программирования Perl, мы импортируем библиотеку (в данном случае это библиотека math
) для работы с комплексными числами. В Python x + yi является аналогом x + y * 1j.
Функции обозначаются с помощью ключевого слова def
. В рамках циклов for
используется ключевое слово range
. В рамках диапазонов, объявляемых с помощью ключевого слова ranage
, должны использоваться целочисленные значения, но, как и в данном случае, при необходимости использования цикла с нецелочисленными значениями, вы можете умножить целочисленное значение из диапазона на нецелочисленное и использовать результат в рамках цикла.
Так как интерпретатор Python автоматически добавляет символ новой строки при использовании функции print
, для получения вывода без символов новой строки нам придется использовать метод объекта строки join
. Обратите внимание на циклы for
в рамках инструкции print/join
, а также методику использования условной инструкции if not ... else
. В данном случае для сохранения результатов работы функции mandelbrot и объединения их в рамках списка используется абстракция списков.
Исполнение сценария на языке Python
JavaScript
Как известно, язык JavaScript был разработан Бренданом Эйхом, работавшим компании Netscape, за 10 дней в 1995 году. В то время компания Netscape предлагала клиентам серверное решение с переносимой версией виртуальной машины Java для исполнения апплетов на стороне сервера и нуждалась в более простом интерпретируемом и доступном для не-программистов языке программирования для взаимодействия с ними. Изначально этот язык носил имя LiveScript и был интегрирован в состав веб-браузера Netscape Navigator в 1995 году, но через некоторое время он был переименован в JavaScript одновременно с добавлением поддержки апплетов Java в этот веб-браузер, что, вероятно, являлось очередным маркетинговым ходом. Это интерпретируемый язык программирования для разработки сценариев, исполняющихся на стороне клиента непосредственно в веб-браузере.
Впоследствии специалисты компании Microsoft осуществили обратный инжениринг JavaScript с целью создания языка JScript, поддержка которого была добавлена в веб-браузер IE3 и веб-сервер IIS в 1996 году. Различия между двумя упомянутыми реализациями языка программирования затрудняли разработку интерактивных веб-сайтов, корректно работающих в обоих веб-браузерах, причем всю вину за это положение вещей начали возлагать именно на JavaScript. По этой причине компания Netscape связалась с организацией по международным стандартам ECMA, в результате чего в 1997 году был опубликован официальный стандарт ECMAScript. Язык JavaScript является лучшей известной реализацией данного стандарта; ActionScript 3 является еще одной его реализацией.
JavaScript опирается на возможности веб-браузера для предоставления объектов и методов, позволяющих взаимодействовать с окружением. Данная архитектура обуславливает потенциальные проблемы с безопасностью, которые были актуальны в прошлом. Некорректное использование возможностей языка может привести к созданию уязвимых сценариев, что нередко встречается в продуктах отдельных разработчиков или крупных компаний.
Скорее всего, это обстоятельство лишь ухудшило репутацию JavaScript, ведь данный язык изначально разрабатывался для неопытных владельцев веб-сайтов, а не профессиональных программистов. Многие из этих неопытных владельцев веб-сайтов просто используют чужие сценарии на своих веб-сайтах без проверки их качества или безопасности.
Однако, по мере роста популярности веб-приложений и в результате создания технологии Ajax (Asynchronous JavaScript and XML: механизм асинхронного взаимодействия с веб-сервером для обновления состояния элементов веб-страницы без ее полной перезагрузки, позволяющий повысить пользовательские качества веб-приложений), репутация JavaScript начала улучшаться, а сам язык стал все чаще использоваться профессионалами. Сегодня язык JavaScript активно используется для создания динамических веб-приложений и веб-страниц - без него практически не обойтись, если необходимо создать современную веб-страницу. Фреймворк Node.js наконец позволил использовать JavaScript не только на стороне клиента, но и на стороне сервера, а API HTML 5 позволяют размещать на страницах множество новых управляющих элементов, улучшая их пользовательские качества - разумеется, не в ущерб безопасности.
Код на языке JavaScript
Вы не сможете инициировать исполнение сценария на языке JavaScript с помощью команды в терминале; для того, чтобы испытать сценарий в работе вам придется открыть с помощью веб-браузера файл hello.html
со следующим содержимым:
<!DOCTYPE HTML> <html> <head></head> <body> <script> alert("Hello World") document.write("Hello World") </script> </body> </html>
Это минималистичная HTML-страница, предназначенная исключительно для исполнения сценария, код которого расположен в рамках тэга <script>
. Фактически данный сценарий осуществляет двукратный вывод строки "Hello world": вызов alert
позволяет вывести всплывающее предупреждение (с автоматически добавленной кнопкой OK); вызов document.write
позволяет вывести упомянутую строку в рамках тела документа HTML. Как и язык Python, язык JavaScript в общем случае не требует наличия символа точки с запятой после каждой инструкции (но позволяет использовать его), причем по поводу того, стоит ли использовать этот символ после каждой из инструкций или все же не стоит, не существует единого устоявшегося мнения. Вы также можете создать отдельный файл сценария с именем file.js
и подключить его к HTML-странице:
А это код сценария для работы с множеством Мандельброта:
В первой строке сценария вы можете установить идентификатор элемента документа, с которым будет работать сценарий на языке JavaScript. (Обратите внимание на то, что элемент тела документа должен иметь идентификатор, то есть, значение параметра id
для корректной работы сценария.)
Функции в JavaScript обозначаются с помощью ключевого слова function
, причем вы можете передавать в функции множество параметров одновременно.
Как и в Python, в JavaScript переменные не должны иметь четко указанных типов, но при этом они должны объявляться с помощью ключевого слова var
перед использованием (хотя это и не обязательно).
Циклы for
работают практически так же, как и в двух описанных выше языках сценариев. Так как в JavaScript нет библиотеки для работы с комплексными числами, нам придется обрабатывать их действительные и мнимые части по отдельности. Инструкция document.write
не позволяет выводить символы пробелов, поэтому вместо них в данном сценарии осуществляется вывод символов обратных кавычек.
Если вам хочется использовать все возможности HTML для вывода более привлекательной версии фрактала (не на основе ASCII-символов), вы также можете поискать соотвествующий код на веб-сайте Rosetta Code (
Процесс отладки сценариев на языке JavaScript может оказаться достаточно сложным из-за того, что сообщения об ошибках не выводятся в теле отображаемого документа; для отладки подобных сценариев может использоваться как ресурс JSLint (www.jslint.com), так и консоль JavaScript вашего веб-браузера
Bash
Bash значительно отличается от Perl, Python и JavaScript, так как является в первую очередь языком для управления задачами и исполнения команд. Но при этом он не перестает быть полноценным языком, который, тем не менее, не очень-то подходит для написания более чем одной-двух страниц кода.
Командная оболочка Bourne shell или sh была выпущена в 1977 году в составе UNIX Version 7 в качестве стандартного интерпретатора команд с поддержкой языка сценариев. Впоследствии она стала стандартной командной оболочкой UNIX и использовалась для выполнения широкого спектра задач, связанных с обслуживанием системы.
Проекту GNU, в рамках которого была начата разработка полностью свободного набора системного программного обеспечения, требовалась свободная полнофункциональная замена командной оболочки sh. В результате в 1989 году Брайн Фокс при финансовой поддержке Фонда Свободного Программного Обеспечения выпустил бета-версию командной оболочки Bash (Bourne-again shell). С того времени она стала стандартной командной оболочкой Linux (при этом такие командные оболочки, как tcsh и zsh также пользуются популярностью). Для того, чтобы узнать название используемой в данной момент командной оболочки вы можете просто выполнить команду echo $SHELL
. Если в вашей системе используется какая-либо из альтернативных командных оболочек, вам будет достаточно выполнить команду /bin/bash
для того, чтобы воспользоваться Bash.
Bash может исполнять отдельные инструкции, вводимые пользователем:
$ echo "Hello World"
Кроме того, она может исполнять файлы сценариев:
#!/bin/bash echo "Hello World"
Bash не требует наличия символов точки с запятой после каждой из команд сценария, а трактует символы новой строки в качестве начальных символов отдельных команд
И это еще не все...
Преимущество языков сценариев заключается в высокой скорости разработки программных продуктов, которая достигается главным образом за счет поддержки динамической типизации. Исходя из этого, популярность языков сценариев, вероятнее всего, тесно связана с появлением механизмов модульного тестирования в инструментарии современных разработчиков; модульное тестирование позволяет снизить ценность строгой типизации, так как оно способно (или, по крайней мере, должно...) выявить как связанные с типами данных, так и некоторые другие ошибки. Разработчики быстрее пишут код на динамических языках программирования, отсутствие затрат времени на компиляцию также положительно сказывается на скорости разработки программных продуктов, а скорость аппаратного обеспечения современных компьютеров нивелирует значение скорости исполнения сценариев (которая, разумеется, ниже, чем у бинарных программ). Конечно же, это всего лишь теоретические измышления; они в принципе не могут быть применимы к каждому из существующих проектов.
Статистические данные, собранные на ресурсах GitHub и StackOverflow в начале 2005 года, говорят о том, что языки JavaScript, Python, Ruby и PHP находятся в первой десятке популярных языков программирования, достойно конкурируя с такими популярными языками, как Java и C/C++. При изучении рынка вакансий также несложно прийти к аналогичным выводам. (Статистические данные доступны по ссылкам