Программирование на языке Ruby - [174]

Шрифт
Интервал

В классе >Shell для создания объектов есть два метода: >new и >cd. Первый создает объект, ассоциированный с текущим каталогом, второй — объект, для которого рабочим будет указанный каталог.

>require "shell"


>sh1 = Shell.new            # Работать в текущем каталоге.

>sh2 = Shell.cd("/tmp/hal") # Работать в каталоге /tmp/hal.

Библиотека >Shell определяет несколько встроенных команд (например, >echo, >cat и >tee) в виде методов. Они всегда возвращают объекты класса >Filter (как и определяемые пользователем команды, с которыми мы вскоре познакомимся).

Класс >Filter понимает, что такое перенаправление ввода/вывода. В нем определены методы (или операторы) ><, >> и >|, которые ведут себя примерно так, как мы ожидаем по многолетнему опыту написания shell-сценариев.

Если методу перенаправления передать в качестве параметра строку, то она будет считаться именем файла. Если же параметром является объект >IO, он используется для операций ввода/вывода. Примеры:

>sh = Shell.new


># Вывести файл motd на stdout.

>sh.cat("/etc/motd") > STDOUT


># Напечатать его еще раз.

>(sh.cat < "/etc/motd") > STDOUT

>(sh.echo "Это тест") > "myfile.txt"


># Добавить строку в конец файла /etc/motd.

>sh.echo("Hello, world!") >> "/etc/motd"


># Вывести два файла на stdout и продублировать (tee) вывод в третий файл.

>(sh.cat "file1" "file2") | (tee "file3") > STDOUT

Отметим, что у оператора >> высокий приоритет. Скобки, которые вы видите в данном примере, в большинстве случаев обязательны. Вот два примера правильного использования и один — неправильного:

># Интерпретатор Ruby понимает такую конструкцию...

>sh.cat("myfile.txt") > STDOUT


># ...и такую тоже.

>(sh.cat "myfile.txt") > STDOUT


># TypeError! (ошибка связана с приоритетами).

>sh.cat "myfile.txt" > STDOUT

Отметим еще, что можно «инсталлировать» системные команды по своему выбору. Для этого служит метод >def_system_command. Ниже определяются два метода: >ls и >ll, которые выводят список файлов в текущем каталоге (в коротком и длинном формате).

># Имя метода совпадает с именем команды...

># Необходим только один параметр:

>Shell.def_system_command "ls"


># А здесь должно быть два параметра:

>Shell.def_system_command "ll", "ls -l"


>sh = Shell.new

>sh.ls > STDOUT # Короткий формат.

>sh.ll > STDOUT # Длинный формат.

Вы, наверное, обратили внимание на то, что в большинстве случаев мы явно отправляем вывод объекту >STDOUT. Связано это с тем, что объект >Shell автоматически вывод команд никуда не направляет. Он просто ассоциирует его с объектом >Filter, который уже может быть связан с файлом или с объектом >IO.

14.3.2. Дополнительные замечания по поводу библиотеки shell.rb

Метод >transact исполняет блок в контексте вызывающего объекта. Таким образом, допустима следующая сокращенная запись:

>sh = Shell.new

>sh.transact do

> echo("Строка данных") > "somefile.txt"

> cat("somefile.txt","otherfile.txt") > "thirdfile"

> cat("thirdfile") | tee("file4") > STDOUT

>end

Итератор >foreach принимает в качестве параметра файл или каталог. Если это файл, он перебирает все его строки, а если каталог — все имена файлов в нем.

>sh = Shell.new


># Напечатать все строки файла /tmp/foo.

>sh.foreach("/tmp/foo") {|l| puts l }


># Вывести список файлов в каталоге /tmp.

>sh.foreach("/tmp") {|f| puts f }

Метод >pushdir запоминает текущий каталог, а метод >popdir делает последний запомненный каталог текущим. У них есть синонимы >pushd и >popd. Метод >pwd возвращает текущий рабочий каталог, его синонимы — >getwd, >cwd и >dir.

>sh = Shell.cd "/home"


>puts sh.pwd # /home

>sh.pushd "/tmp"

>puts sh.pwd # /tmp


>sh.popd

>puts sh.pwd # /home

Для удобства в класс >Shell импортируются методы из различных источников, в том числе из класса >File, модуля >FileTest и библиотеки >ftools.rb. Это избавляет от необходимости выполнять >require, >include, создавать объекты, квалифицировать вызовы методов и т. д.

>sh = Shell.new

>flag1 = sh.exist? "myfile"     # Проверить существование файла.

>sh.delete "somefile"           # Удалить файл.

>sh.move "/tmp/foo", "/tmp/bar" # Переместить файл.

У библиотеки >Shell есть и другие возможности, которые мы здесь не рассматриваем. Дополнительную информацию ищите в документации.

14.4. Переменные окружения

Иногда необходимо обращаться к переменным окружения, которые являются связующим звеном между программой и внешним миром. Переменные окружения — это просто метки, связанные с некоторым текстом (обычно небольшим); в них хранятся, например, пути к файлам, имена пользователей и т.п.

Переменные окружения широко применяются в ОС UNIX. Система Windows (а еще раньше MS-DOS) позаимствовала эту идею у UNIX, поэтому приведенные ниже коды будут работать на обеих платформах.

14.4.1. Чтение и установка переменных окружения

Глобальная константа >ENV — это хэш, с помощью которого можно читать и изменять переменные окружения. В примере ниже мы читаем значение переменной >PATH, (в Windows вместо двоеточия нужно употреблять точку с запятой):

>bypath = ENV["PATH"]

># А теперь получим массив...

>dirs = mypath.split(":")

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


Рекомендуем почитать
Графика DirectX в Delphi

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


Вторая жизнь старых компьютеров

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


DirectX 8. Начинаем работу с DirectX Graphics

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


Симуляция частичной специализации

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


Обработка событий в С++

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


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.