Ruby Advanced

Ruby Advanced

Ruby Advanced Часть I Марченко Светлана Ruby Advanced Графические интерфейсы для Ruby Потоки в Ruby Сценарии и системное администрирование Тестирование и отладка Создание пакетов и распространение программ Ruby и Web приложения Ruby tricks Графические интерфейсы для Ruby (Tk, GTK+, FOX, QtRuby) Ruby/Tk Tk — платформо-независимая система Perl, Tcl (Perl/Tk) Переносимость, стабильность Корневой контейнер с виджетами + геометрический менеджер(pack, grid, place) Блоки вычисляются в контексте вызываемого объекта (instance_eval), а не в контексте вызывающей программы Ruby/GTK2 Ruby/GTK2 (GIMP Toolkit) Лежит в основе графического менеджера GNOME, но MS Windows, MAC OS X c X Window System Расширение Ruby/GTK2 (GTK+ 2.0) НЕ ПУТАТЬ c Ruby/GTK (GTK+ 1.2), которое несовместимо и считается устаревшим GNU LGPL Концепция фреймов, диалогов, окон и менеджеров размещения Располагает богатым набором виджетов (стандартные + более сложные, например, деревья, многоколонные списки) GTK+ написана на С, но спроектирована в ОО манере Ruby/GTK2 предоставляет объектно-ориентированный API GTK2 написана вручную → API выдержан в духе Ruby (с использованием блоков, необязательных аргументов и т.д) GTK+ на базе Glib, Pango, ATK, Cairo, GDK Графические интерфейсы для Ruby Недостатки недостаточно богатый набор стандартных диалоговых окон все строки должны быть в UTF-8 (в начало сценария $KCODE= "U") FXRuby (FOX — Free Objects for X) относительно новая технология акцент на быстродействие и межплатформенную совместимость не обертка платформенного API написана на С++, объектно-ориентированная FXRuby — привязка к Ruby библиотеки FOX (Lyle Johnson) также перенесена на платформу MS Windows парадигма сообщение/получатель парадигма автоматического обновления широкие возможности(связь между приложениями и его окружением, сигналы) гибкость (поддерживает API для работы с OpenGL) Графические интерфейсы для Ruby QtRuby акцент на кросс-платформенность (Windows, Mac, UNIX) Qt (GPL and Commercial License) концепция сигналов и слотов Qt написан на С++, для Ruby вводится некая избыточность для возможности «рубистских »выражений Qt::Widget::minimumSizeHint Qt::Widget::minimum_size_hint widget.setMinimumSize(50); widget.minimumSize = 50; widget.minimum_size = 50; a.isVisible(); a.visible? Потоки в Ruby Потоки определены на пользовательском уровне и не зависят от ОС Создание потоков thread = Thread.new #действия этого потока end Передача им входной информации (параметры, передаваемые в блок) Останов Синхронизация – может быть очень дорогой Создание потоков и манипулирование ими new возвращает объект типа Thread (синоним fork) a = 1 b = 2 c = 3 thread2 = Thread.new(a,b) do |a, x| с = 4 # доступ ко всем переменным из внешней области видимости а = 2 # любые другие манипуляции end Доступ к локальным переменным потока через специальный механизм (организован как хэш) из любого места видимости объекта Thread Thread.current[:var1] = «var_value» #внутри потока Thread.current[«var2»] = 3 x = thread2[:var1] y = thread2.key?(«var2») # проверяет используется ли в потоке указанное имя Опрос и изменение состояния потока list — массив «живых» потоков main — возвращает ссылку на главный поток current — позволяет потоку идентифицировать себя exit, pass, start, stop, kill — позволяют управлять потоком изнутри и извне Thread.exit, Thread.pass Не существует метода экземпляра stop → поток только может приостановить собственное выполнение, но не выполнение другого потока alive?, stop?, status (run, sleep, nil) $SAFE, safe_level join — не может быть вызван самим потоком у себя, только у другого потока Thread.list.each{ |t| t.join if t != Thread.main } интерпретатор обнаружит тупиковую ситуацию: два потока вызвали друг у друга join метод value неявно вызывает join Опрос и изменение состояния потока (пример) max = 1000 thr = Thread.new do sum = 0 1.upto(max) {|i| sum += i} sum end guess = (max*(max+1))/2 if guess == thr.value puts «правильно » else puts «неправильно » end Обработка исключений и группы потоков Theread.abort_on_exception = true (t1.abort_on_exception = true) Группы позволяют логически связывать потоки (по умолчанию все потоки в группе Default) file_threads = ThreadGroup.new file_threads.add f1 file_threads.add f2 В любой момент поток принадлежит только одной группе class ThreadGroup (new, add, list) В класс ThreadGroup можно добавлять свои методы, например: возобновление потоков в группе групповое ожидание групповое завершение class ThreadGroup def join #... end ... end Синхронизация потоков Критические секции — простейший способ синхронизации Thread.critical = true #код , который хотим защитить Thread.critical = false Применять только в самых простых случаях! Возможны такие комбинации операций с потоками, что поток планируется даже, если другой поток в критической секции. Синхронизация доступа к ресурсам (mutex.rb) lock, try_lock, unlock mutex = Mutex.new mutex.lock #если мьютекс занят, ждет освобождения #something mutex.unlock Синхронизация потоков mutex.rb if mutex.try_lock #не ждет освобождения, возвращает false, если занят #something else #something end mutex.synchronize do #something end synchronize захватывает мьютекс и автоматически освобождает его объекты могут выступать в роли мьютекса Библиотека mutex_m с модулем Mutex_m, который расширяет пользовательский класс: у объектов класса можно вызывать методы мьютекса Синхронизация потоков Библиотека sync.rb предоставляет еще один способ синхронизации: блокировка со счетчиком locked?, shared?, exclusive?, lock, unlock, try_lock Условная переменная — используется вместе с мьютексами (очередь потоков) require ©thread© @music = Mutex.new @violin = ConditionalVariable.new @violins_free = 2 @music.synchronize do @violin.wait(@music) while @violins_free == 0 #... end Синхронизация потоков monitor.rb Monitor(monitor.rb) — еще один способ синхронизации: захваты одного и того же мьютекса могут быть вложенными Например, может понадобиться при рекурсивном вызове метода применяется для расширения класса class ConditionalVariable в библиотеке monitor.rb — расширенный по сравнению с условными переменными в Thread: new_cond — создание условной переменной wait_until, wait_while — методы, блокирующие поток в ожидании выполнения условия wait(timeout) - можно определить timeout при ожидании (в секундах) Сценарии и системное администрирование Универсальность Ruby позволяет использовать его для взаимодействия с ОС на высоком уровне (все, что есть в bash, можно реализовать с Ruby) Запуск внешних программ Перехват вывода программы Манипулирование процессами Стандартный ввод/вывод Не всегда удобно использовать из-за сложности синтаксиса (использование различных библиотек) Библиотека Shell (не всегда работает на Windows) ActiveScriptRuby — язык, предоставляющий мост между COM и Ruby для Windows приложений Ruby можно использовать в html <script language= «RubySctipt»> # Здесь код на Ruby </script> Сценарии и системное администрирование shell.rb sh = Shell.new #создали объект, ассоциированныйс текущимкаталогом sh1 = Shell.cd (©©/tmp/hal©©) #объект , ассоциированный с указанным каталогом Встроенные команды (например, echo, cat, tee) возвращают объекты класса Filter sh.cat (©©/etc/modt©©) > STDOUT ! Автоматически shell вывод команд никуда не направляет Class Filter понимает, что такое перенаправление ввода/вывода Операторы >, <, | Метод def_system_command позволяет «инсталлировать» системные команды по своему выбору Shell.def_system_command ©©ls©© Различные сценарии AllInOneRuby — дистрибутив Ruby в одном файле (интерпретатор, системные классы, стандартные библиотеки) Tar2RubyScript — программа получает дерево каталогов и создает самораспаковывающийся архив: Ruby программа и tar архив (если не библиотека, нужен файл init.rb) Созданный архив можно запустить на любой машине, где установлен Ruby RubyScript2Exe — преобразует Ruby приложение в один двоичный файл(подходит для Windows, Linux, Mac OS X): Не компилятор Собирает файлы, являющиеся частью установленного дистрибутива Ruby на вашей машине (не нуждается в кросс-компиляции) Исполняемый файл «усечен» - в нем нет неиспользуемых библиотек Не требует установленного Ruby для запуска, т. к. включает интерпретатор Ruby, среду исполнения и необходимые внешние программы Модуль Etc — получает информацию из /etc/passwd и /etc/group login пользователя, от имени которого запущена программа Структуру passwd (name, dir, shell) Аналогичные функции для групп Тестирование и отладка Библиотека Test::Unit (включена в дистрибутив с 2001 года) для анализа тестового кода применяется отражение для наследника класса Test::Unit::TestCase все методы, имена которых начинаются с test считаются тестовыми тесты выполняются в алфавитном порядке методы setup, teardown используются для создания особой среды выполнения тестов, вызываются для каждого теста утверждения assert_equal (expected, actual) любой исполнитель тестов можно вызвать методом run и передать параметр, описывающий набор тестов Тестирование и отладка Комплект инструментов ZenTest Основной инструмент — исполняемая программа, которая генерирует файл с тестами тестируемый класс — основа для создания тестового класса: Создается класс с именем тестируемого класса и префикса Test, наследованный от Test::Unit::TestCase, и все методы c префиксом test_ Разработчику (или тестеру) остается только реализовать тело тестовых методов unit_diff — программа, которую следует вызывать как фильтр после тестовой программы autotest — прогоняет все тесты по мере их обновления multiruby — позволяет

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    31 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us