Читать книги » Книги » Компьютеры и Интернет » Программирование » Хэл Фултон - Программирование на языке Ruby

Хэл Фултон - Программирование на языке Ruby

Читать книгу Хэл Фултон - Программирование на языке Ruby, Хэл Фултон . Жанр: Программирование.
Хэл Фултон - Программирование на языке Ruby
Название: Программирование на языке Ruby
ISBN: -
Год: -
Дата добавления: 3 июль 2019
Количество просмотров: 341
(18+) Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних просмотр данного контента СТРОГО ЗАПРЕЩЕН! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту для удаления материала.
Читать онлайн

Программирование на языке Ruby читать книгу онлайн

Программирование на языке Ruby - читать онлайн , автор Хэл Фултон
Ruby — относительно новый объектно-ориентированный язык, разработанный Юкихиро Мацумото в 1995 году и позаимствовавший некоторые особенности у языков LISP, Smalltalk, Perl, CLU и других. Язык активно развивается и применяется в самых разных областях: от системного администрирования до разработки сложных динамических сайтов.Книга является полноценным руководством по Ruby — ее можно использовать и как учебник, и как справочник, и как сборник ответов на вопросы типа «как сделать то или иное в Ruby». В ней приведено свыше 400 примеров, разбитых по различным аспектам программирования, и к которым автор дает обстоятельные комментарии.Издание предназначено для программистов самого широкого круга и самой разной квалификации, желающих научиться качественно и профессионально работать на Ruby.
Перейти на страницу:

Посмотрим на вариацию этой идеи. Что если вы захотели бы применить случайные числа в каком-нибудь приложении? Поскольку обслуживающая программа на стороне сервера позволяет указать количество возвращаемых чисел, то было бы логично сохранить их в буфере. Учитывая, что при обращении к удаленному серверу задержки неизбежны, следует сразу заполнить буфер во избежание лишних запросов по сети.

В листинге 18.5 эта мысль реализована. Буфер заполняется отдельным потоком и совместно используется всеми экземплярами класса. Размер буфера и «нижняя отметка» (@slack) настраиваются; какие значения задать в реальной программе, зависит от величины задержки при обращении к серверу и от того, как часто приложение выбирает случайное число из буфера.

Листинг 18.5. Генератор случайных чисел с буферизацией

require "net/http"

require "thread"

class TrueRandom

 def initialize(min=nil,max=nil,buff=nil,slack=nil)

  @buffer = []

  @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.

Наконец, покажем еще, как вернуть только тело сообщения, игнорируя все заголовки.

module Net

 class POPMail

  def body

   # Пропустить байты заголовка

   self.all[self.header.size..-1]

  end

 end

end

Если вы предпочитаете протокол IMAP, а не POP3, обратитесь к разделу 18.2.5

18.2.4. Отправка почты по протоколу SMTP

Это понял бы и пятилетний ребенок. Дайте мне пятилетнего ребенка.

Гроучо Маркс

Название «простой протокол электронной почты» (Simple Mail Transfer Protocol — SMTP) не вполне правильно. Если он и «простой», то только по сравнению с более сложными протоколами.

Конечно, библиотека smtp.rb скрывает от программиста большую часть деталей протокола. Но, на наш взгляд, эта библиотека интуитивно не вполне очевидна и, пожалуй, слишком сложна (надеемся, что в будущем это изменится). В этом разделе мы приведем несколько примеров, чтобы помочь вам освоиться.

В классе Net::SMTP есть два метода класса: new и start. Метод new принимает два параметра: имя сервера (по умолчанию localhost) и номер порта (по умолчанию 25).

Метод start принимает следующие параметры:

• server — доменное имя или IP-адрес SMTP-сервера; по умолчанию это "localhost";

• port — номер порта, по умолчанию 25;

• domain — доменное имя отправителя, по умолчанию ENV["HOSTNAME"];

• account — имя пользователя, по умолчанию nil;

• password — пароль, по умолчанию nil;

• authtype — тип авторизации, по умолчанию :cram_md5.

Обычно большую часть этих параметров можно не задавать.

Если метод start вызывается «нормально» (без блока), то он возвращает объект класса SMTP. Если же блок задан, то этот объект передается прямо в блок.

У объекта SMTP есть метод экземпляра sendmail, который обычно и занимается всеми деталями отправки сообщения. Он принимает три параметра:

Перейти на страницу:
Комментарии (0)