Чтение онлайн

ЖАНРЫ

Программирование на языке Ruby
Шрифт:

puts "Родитель: alpha = #{a}"

puts "Родитель: beta = #{b}"

Программа выводит следующие строки:

Родитель: alpha = 123

Родитель: beta = 456

 Потомок: alpha = 123

 Потомок: beta = 789

Родитель: alpha = 123

Родитель: beta = 456

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

исполняется в подоболочке, то после ее завершения все сделанные изменения переменных окружения не будут видны в текущей оболочке.

14.4.2. Хранение переменных окружения в виде массива или хэша

Важно понимать, что объект

ENV
— не настоящий хэш, а лишь выглядит как таковой. Например, мы не можем вызвать для него метод
invert
; будет возбуждено исключение
NameError
, поскольку такого метода не существует. Причина такой реализации в том, что существует тесная связь между объектом
ENV
и операционной системой; любое изменение хранящихся в нем значений отражается на состоянии ОС, а такое поведение с помощью простого хэша не смоделируешь.

Однако имеется метод

to_hash
, который вернет настоящий хэш, отражающим текущее состояние:

envhash = ENV.to_hash

val2var = envhash.invert

Получив такой хэш, мы можем преобразовать его к любому другому виду (например, в массив):

envarr = ENV.to_hash.to_a

Обратное присваивание объекту

ENV
недопустимо, но при необходимости можно пойти обходным путем:

envhash = env.to_hash

# Выполняем произвольные операции... и записываем обратно в ENV.

envhash.each {|k,v| ENV[k] = v }

14.4.3. Импорт переменных окружения как глобальных переменных

Существует библиотечка

importenv.rb
, которая импортирует все переменные окружения, сопоставляя им глобальные переменные программы:

require "importenv"

# Теперь переменные окружения стали глобальными переменными...

# Например, $PWD и $LOGNAME

where = $PWD

who = $LOGNAME

puts "В каталоге #{where}, вошел как #{who}"

Поскольку библиотека

importenv
пользуется библиотекой
trace_var
, отражение на самом деле двустороннее: если присвоить глобальной переменной новое значение, реальная переменная окружения получит то же значение.

require "importenv"

puts "Мой путь #$PATH"

# Печатается: /usr/local/bin:/usr/bin:/usr/ucb:/etc:.

$PATH = "/ruby-1.8.0:" + $PATH

puts "Моя переменная $PATH теперь равна #{ENV['PATH']}"

# Печатается: /ruby-1.8.0:/usr/local/bin:/usr/bin:/usr/ucb:/etc:.

Еще

раз подчеркнем, что любые изменения переменных окружения, выполненные внутри программы на Ruby, не отражаются на их значениях, видимых вне этой программы.

14.5. Сценарии на платформе Microsoft Windows

Как и на лыжном курорте, где девушки ищут мужей, а мужья — девушек, ситуация не так симметрична, как может показаться на первый взгляд.

Алан Линдсей Маккей

Уже отмечалось, что Ruby больше любит ОС UNIX. В каком-то смысле это правда: язык разрабатывался в среде UNIX, в ней лучше всего и работает. Сейчас он, впрочем, перенесен на другие платформы, в том числе на Macintosh; ведется даже работа по переносу на Palm OS. Но если UNIX — основная платформа, то следующая по значимости — Windows.

Пользователи Windows не брошены на произвол судьбы. Существует немало инструментов и библиотек для этой платформы, а разрабатывается еще больше, многие аспекты Ruby, даже механизм потоков, изначально не зависят от платформы. Наибольшие трудности возникают при управлении процессами, выполнении ввода/вывода и других операций низкого уровня.

В прошлом существовало несколько вариантов Ruby для Windows. Интерпретатор мог быть собран компилятором gcc или Visual С, его работа могла зависеть от наличия библиотеки Cygwin DLL и т.д. Но в последние годы появился «моментальный» инсталлятор для Windows (см. раздел 14.6).

Среда изменяется слишком быстро, чтобы можно было ее сейчас документировать, однако в этом разделе мы все же рассмотрим некоторые вопросы написания сценариев и автоматизации на платформе Windows. Описанные приемы и утилиты должны работать в любой ОС. Если возникнут проблемы, сообщество придет на помощь.

14.5.1. Расширение Win32API

Расширение

Win32API
— исключительно мощный инструмент, если вы собираетесь программировать на относительно низком уровне. Оно позволяет вызывать из Ruby функции Windows API, находящиеся в любой DLL.

Указанная функция становится объектом, а методу new передаются параметры, точно описывающие функцию. Первый параметр — строка, идентифицирующая DLL, в которой находится функция (например,

crtdll
). Второй параметр — имя самой функции, третий — массив строк, описывающих типы параметров функции (массив импорта), а четвертый — строка, описывающая тип возвращаемого значения (строка экспорта).

Массив импорта может содержать следующие значения (регистр не играет роли):

I целое

L число

N число

P указатель на строку

Строка экспорта также может содержать любое из этих значений, а также значение «V», означающее «void».

После того как объект создан, можно обратиться к его методу

call
для вызова функции Windows. Синоним —
Call
.

В примере ниже мы вызываем функцию

GetCursorPos
, которая возвращает указатель на структуру
POINT
. Эта структура состоит из двух полей типа
long
. Чтобы получить их значения, мы можем воспользоваться методом
unpack
:

Поделиться с друзьями: