Программирование на языке Ruby - [205]
> @site = "www.random.org"
> if ! defined? @init_flag
> # Принять умолчания, если они не были заданы явно И
> # это первый созданный экземпляр класса...
> @min = min || 0
> @max = max || 1
> @bufsize = buff || 1000
> @slacksize = slack || 300
> @mutex = Mutex.new
> @thread = Thread.new { fillbuffer }
> @init_flag = TRUE # Значение может быть любым.
> else
> @min = min || @min
> @max = max || @max
> @bufsize = buff || @bufsize
> @slacksize = slack || @slacksize
> end
> @url = "/cgi-bin/randnum" +
> "?num=#@bufsize&min=#@min&max=#@max&col=1"
> end
> def fillbuffer
> h = Net::HTTP.new(@site, 80)
> resp, data = h.get(@url, nil)
> @buffer += data.split
> end
> def rand
> num = nil
> @mutex.synchronize { num = @buffer.shift }
> if @buffer.size < @slacksize
> if ! @thread.alive?
> @thread = Thread.new { fillbuffer }
> end
> end
> if num == nil
> if @thread.alive?
> @thread.join
> else
> @thread = Thread.new { fillbuffer }
> @thread.join
> end
> @mutex.synchronize { num = @buffer.shift }
> end
> num.to_i
> end
>end
>t = TrueRandom.new(1,6,1000,300)
>count = {1=>0, 2=>0, 3=>0, 4=>0, 5=>0, 6=>0}
>10000.times do |n|
> x = t.rand
> count[x] += 1
>end
>p count
># При одном прогоне:
># {4=>1692, 5=>1677, 1=>1678, 6=>1635, 2=>1626, 3=>1692}
18.2.2. Запрос к официальному серверу времени
Как мы и обещали, приведем программу для обращения к NTP-серверу в сети (NTP — Network Time Protocol (синхронизирующий сетевой протокол). Показанный ниже код заимствован с небольшой переработкой у Дэйва Томаса.
>require "net/telnet"
>timeserver = "www.fakedomain.org"
>local = Time.now.strftime("%H:%M:%S")
>tn = Net::Telnet.new("Host" => timeserver,
> "Port" => "time",
> "Timeout" => 60,
> "Telnetmode" => false)
>msg = tn.recv(4).unpack('N')[0]
># Преобразовать смещение от точки отсчета
>remote = Time.at(msg — 2208988800).strftime("%H:%M:%S")
>puts "Местное : #{local}"
>puts "Удаленное : #{remote}"
Мы устанавливаем соединение и получаем четыре байта. Они представляют 32-разрядное число в сетевом (тупоконечном) порядке байтов. Это число преобразуется в понятную форму, а затем — из смещения от точки отсчета в объект >Time
.
Мы не указали имя реального сервера. Дело в том, что его полезность часто зависит от того, где вы находитесь. Кроме того, многие серверы ограничивают доступ, так что для запроса вы должны получить разрешение или хотя бы уведомить владельца. Поисковая машина поможет найти открытый NTP-сервер в радиусе 1000 км от вас.
18.2.3. Взаимодействие с РОР-сервером
Многие серверы электронной почты пользуются почтовым протоколом (Post Office Protocol — POP). Имеющийся в Ruby класс >POP3
позволяет просматривать заголовки и тела всех сообщений, хранящихся для вас на сервере, и обрабатывать их как вы сочтете нужным. После обработки сообщения можно удалить.
Для создания объекта класса >Net::POP3
нужно указать доменное имя или IP-адрес сервера; номер порта по умолчанию равен 110. Соединение устанавливается только после вызова метода >start
(которому передается имя и пароль пользователя).
Вызов метода >mails
созданного объекта возвращает массив объектов класса >POPMail
. (Имеется также итератор >each
для перебора этих объектов.)
Объект >POPMail
соответствует одному почтовому сообщению. Метод >header
получает заголовки сообщения, а метод >all
— заголовки и тело (у метода >all
, как мы вскоре увидим, есть и другие применения).
Фрагмент кода стоит тысячи слов. Вот пример обращения к серверу с после дующей распечаткой темы каждого сообщения:
>require "net/pop"
>pop = Net::POP3.new("pop.fakedomain.org")
>pop.start("gandalf", "mellon") # Имя и пароль пользователя.
>pop.mails.each do |msg|
> puts msg.header.grep /^Subject: /
>end
Метод >delete
удаляет сообщение с сервера. (Некоторые серверы требуют, чтобы POP-соединение было закрыто методом >finish
, только тогда результат удаления становится необратимым.) Вот простейший пример фильтра спама:
>require "net/pop"
>pop = Net::POP3.new("pop.fakedomain.org")
>pop.start("gandalf", "mellon") # Имя и пароль пользователя.
>pop.mails.each do |msg|
> if msg.all =~ /.*make money fast.*/
> msg.delete
> end
>end
>pop.finish
Отметим, что при вызове метода >start
можно также задавать блок. По аналогии с методом >File.open
в этом случае открывается соединение, исполняется блок, а затем соединение закрывается.
Метод >all
также можно вызывать с блоком. В блоке просто перебираются все строки сообщения, как если бы мы вызвали итератор >each
для строки, возвращенной методом >all
.
># Напечатать все строки в обратном порядке... полезная штука!
>msg.all { |line| print line.reverse }
># To же самое...
>msg.all.each { |line| print line.reverse }
Методу >all
можно также передать объект. В таком случае для каждой строчки (>line
) в полученной строке (string) будет вызван оператор конкатенации (><<
). Поскольку в различных объектах он может быть определен по-разному, в результате такого обращения возможны самые разные действия:
>arr = [] # Пустой массив.
>str = "Mail: " # String.
>out = $stdout # Объект IO.
>msg.all(arr) # Построить массив строчек.
>msg.all(str) # Конкатенировать с str.
>msg.all(out) # Вывести на stdout.
Наконец, покажем еще, как вернуть только тело сообщения, игнорируя все заголовки.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Сейчас во многих школах, институтах и других учебных заведениях можно встретить компьютеры старого парка, уже отслужившие свое как морально, так и физически. На таких компьютерах можно изучать разве что Dos, что далеко от реалий сегодняшнего дня. К тому же у большинства, как правило, жесткий диск уже в нерабочем состоянии. Но и выбросить жалко, а новых никто не дает. Различные спонсоры, меценаты, бывает, подарят компьютер (один) и радуются, как дети. Спасибо, конечно, большое, но проблемы, как вы понимаете, этот компьютер в общем не решает, даже наоборот, усугубляет, работать на старых уже как-то не хочется, теперь просто есть с чем сравнивать.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.