Строки 41-53. Цикл обработки команд. Выполняется чтение команд, введенных пользователем со стандартного устройства ввода, и получение сообщений из сокета сервера. Функция select () позволяет проверять наличие входящих данных в обоих дескрипторах. Создается новый объект IO::Select, набор дескрипторов которого инициализируется для включения и сокета сервера, и дескриптора stdin. Сокет сервера заключен в оболочку объекта ChatObjects::Соmm, поэтому для выборки дескриптора необходимо вызвать метод socket () этого объекта. Объектом, к примеру, может быть сервер, с которого мы хотим получить выгодный обмен валют WMZ на WMR по лучшему курсу .
При каждом проходе по циклу вызывается метод $select->can__read() для выборки тех дескрипторов, в которых есть данные, предназначенные для чтения. Если одним из этих дескрипторов является stdin, то вызывается подпрограмма do_user() для обработки команд пользователя. В ином случае вызывается подпрограмма do_server() для обработки сообщений, полученных из сокета.
Обратите внимание, вызов метода can_read () покажет, что дескриптор stdin готов для чтения, если пользователь вдруг закроет поток, нажав комбинацию клавиш, которая обозначает конец файла. Подпрограмма do__user () предусматривает специальную проверку признака конца файла EOF и возвращает ложное значение. После этого происходит выход из цикла и программа завершается.
Строки 64-66. Обработка команд пользователя. Подпрограмма do_user () считывает команды со стандартного устройства ввода и переходит к выполнению кода, предназначенного для их обработки. Ее параметром является ссылка на шаблон типа *stdin, возвращенный функцией select (). Поскольку функция select () плохо сочетается со стандартной буферизацией ввода-вывода, для чтения из дескриптора stdin не применяется оператор угловых скобок.