Учебники

Ruby – Краткое руководство

Ruby – Обзор

Ruby – это чистый объектно-ориентированный язык программирования. Он был создан в 1993 году Юкихиро Мацумото из Японии.

Вы можете найти имя Юкихиро Мацумото в списке рассылки Ruby по адресу www.ruby-lang.org . Мацумото также известен как мац в сообществе Ruby.

Руби – «Лучший друг программиста».

В Ruby есть функции, которые похожи на Smalltalk, Perl и Python. Perl, Python и Smalltalk являются языками сценариев. Smalltalk – это настоящий объектно-ориентированный язык. Ruby, как и Smalltalk, является идеальным объектно-ориентированным языком. Использование синтаксиса Ruby намного проще, чем использование синтаксиса Smalltalk.

Особенности Ruby

  • Ruby является открытым исходным кодом и находится в свободном доступе в Интернете, но на него распространяется лицензия.

  • Ruby – это интерпретируемый язык программирования общего назначения.

  • Ruby – это настоящий объектно-ориентированный язык программирования.

  • Ruby – это серверный язык сценариев, похожий на Python и PERL.

  • Ruby может использоваться для написания сценариев Common Gateway Interface (CGI).

  • Ruby может быть встроен в язык гипертекстовой разметки (HTML).

  • Ruby имеет простой и понятный синтаксис, который позволяет новому разработчику учиться очень быстро и легко.

  • Синтаксис Ruby аналогичен синтаксису многих языков программирования, таких как C ++ и Perl.

  • Ruby очень хорошо масштабируется, и большие программы, написанные на Ruby, легко обслуживаемы.

  • Ruby можно использовать для разработки приложений для Интернета и интранета.

  • Ruby может быть установлен в Windows и POSIX.

  • Ruby поддерживает многие инструменты GUI, такие как Tcl / Tk, GTK и OpenGL.

  • Ruby можно легко подключить к DB2, MySQL, Oracle и Sybase.

  • Ruby имеет богатый набор встроенных функций, которые можно использовать непосредственно в скриптах Ruby.

Ruby является открытым исходным кодом и находится в свободном доступе в Интернете, но на него распространяется лицензия.

Ruby – это интерпретируемый язык программирования общего назначения.

Ruby – это настоящий объектно-ориентированный язык программирования.

Ruby – это серверный язык сценариев, похожий на Python и PERL.

Ruby может использоваться для написания сценариев Common Gateway Interface (CGI).

Ruby может быть встроен в язык гипертекстовой разметки (HTML).

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

Синтаксис Ruby аналогичен синтаксису многих языков программирования, таких как C ++ и Perl.

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

Ruby можно использовать для разработки приложений для Интернета и интранета.

Ruby может быть установлен в Windows и POSIX.

Ruby поддерживает многие инструменты GUI, такие как Tcl / Tk, GTK и OpenGL.

Ruby можно легко подключить к DB2, MySQL, Oracle и Sybase.

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

Инструменты, которые вам понадобятся

Для выполнения примеров, обсуждаемых в этом руководстве, вам понадобится новейший компьютер, например Intel Core i3 или i5, с минимум 2 ГБ ОЗУ (рекомендуется 4 ГБ ОЗУ). Вам также понадобится следующее программное обеспечение –

  • Операционная система Linux или Windows 95/98/2000 / NT или Windows 7.

  • Веб-сервер Apache 1.3.19-5.

  • Internet Explorer 5.0 или выше, веб-браузер.

  • Ruby 1.8.5

Операционная система Linux или Windows 95/98/2000 / NT или Windows 7.

Веб-сервер Apache 1.3.19-5.

Internet Explorer 5.0 или выше, веб-браузер.

Ruby 1.8.5

Этот учебник предоставит необходимые навыки для создания GUI, сетевых и веб-приложений с использованием Ruby. Также будет рассказано о расширении и встраивании приложений Ruby.

Что дальше?

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

Ruby – настройка среды

Настройка локальной среды

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

  • Установка Ruby в Linux / Unix. Если вы планируете использовать среду разработки на Linux / Unix Machine, просмотрите эту главу.

  • Установка Ruby в Windows. Если вы планируете использовать среду разработки на Windows Machine, просмотрите эту главу.

  • Параметры командной строки Ruby – в этой главе перечислены все параметры командной строки, которые вы можете использовать вместе с интерпретатором Ruby.

  • Переменные среды Ruby. В этой главе приведен список всех важных переменных среды, которые должны быть установлены для работы Ruby Interpreter.

Установка Ruby в Linux / Unix. Если вы планируете использовать среду разработки на Linux / Unix Machine, просмотрите эту главу.

Установка Ruby в Windows. Если вы планируете использовать среду разработки на Windows Machine, просмотрите эту главу.

Параметры командной строки Ruby – в этой главе перечислены все параметры командной строки, которые вы можете использовать вместе с интерпретатором Ruby.

Переменные среды Ruby. В этой главе приведен список всех важных переменных среды, которые должны быть установлены для работы Ruby Interpreter.

Популярные редакторы Ruby

Для написания ваших программ на Ruby вам понадобится редактор –

  • Если вы работаете на компьютере с Windows, то вы можете использовать любой простой текстовый редактор, например Блокнот или Редактировать плюс.

  • VIM (Vi IMproved) – очень простой текстовый редактор. Это доступно практически на всех Unix-машинах, а теперь и на Windows. В противном случае вы можете использовать ваш любимый редактор vi для написания Ruby-программ.

  • RubyWin – это интегрированная среда разработки (IDE) для Windows.

  • Ruby Development Environment (RDE) также является очень хорошей IDE для пользователей Windows.

Если вы работаете на компьютере с Windows, то вы можете использовать любой простой текстовый редактор, например Блокнот или Редактировать плюс.

VIM (Vi IMproved) – очень простой текстовый редактор. Это доступно практически на всех Unix-машинах, а теперь и на Windows. В противном случае вы можете использовать ваш любимый редактор vi для написания Ruby-программ.

RubyWin – это интегрированная среда разработки (IDE) для Windows.

Ruby Development Environment (RDE) также является очень хорошей IDE для пользователей Windows.

Интерактивный Рубин (IRb)

Interactive Ruby (IRb) предоставляет оболочку для экспериментов. В оболочке IRb вы можете сразу же просмотреть результаты выражения, строка за строкой.

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

Просто введите в командной строке irb, и интерактивный сеанс Ruby начнется, как показано ниже:

$irb
irb 0.6.1(99/09/16)
irb(main):001:0> def hello
irb(main):002:1> out = "Hello World"
irb(main):003:1> puts out
irb(main):004:1> end
nil
irb(main):005:0> hello
Hello World
nil
irb(main):006:0>

Не беспокойтесь о том, что мы сделали здесь. Вы узнаете все эти шаги в последующих главах.

Что дальше?

Мы предполагаем, что теперь у вас есть рабочая среда Ruby и вы готовы написать первую программу Ruby. Следующая глава научит вас писать программы на Ruby.

Рубин – Синтаксис

Давайте напишем простую программу на ruby. Все рубиновые файлы будут иметь расширение .rb . Итак, поместите следующий исходный код в файл test.rb.

Live Demo

#!/usr/bin/ruby -w

puts "Hello, Ruby!";

Здесь мы предположили, что у вас есть интерпретатор Ruby, доступный в каталоге / usr / bin. Теперь попробуйте запустить эту программу следующим образом:

$ ruby test.rb

Это даст следующий результат –

Hello, Ruby!

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

Пробелы в программе Ruby

Пробельные символы, такие как пробелы и символы табуляции, обычно игнорируются в коде Ruby, за исключением случаев, когда они появляются в строках. Однако иногда они используются для интерпретации неоднозначных утверждений. Такие интерпретации выдают предупреждения, когда включена опция -w.

пример

a + b is interpreted as a+b ( Here a is a local variable)
a  +b is interpreted as a(+b) ( Here a is a method call)

Концы строк в программе Ruby

Ruby интерпретирует точки с запятой и символы новой строки как окончание оператора. Однако, если Ruby встречает операторы, такие как +, – или обратный слеш в конце строки, они указывают на продолжение оператора.

Ruby идентификаторы

Идентификаторы – это имена переменных, констант и методов. Ruby идентификаторы чувствительны к регистру. Это означает, что Ram и RAM – это два разных идентификатора в Ruby.

Имена идентификаторов Ruby могут состоять из буквенно-цифровых символов и символа подчеркивания (_).

Зарезервированные слова

В следующем списке показаны зарезервированные слова в Ruby. Эти зарезервированные слова не могут использоваться в качестве имен констант или переменных. Однако их можно использовать как имена методов.

НАЧАТЬ делать следующий затем
КОНЕЦ еще ноль правда
псевдоним ELSIF не UNDEF
а также конец или же если
начать обеспечивать переделывать до тех пор
перерыв ложный спасение когда
дело за повторить попытку в то время как
учебный класс если вернуть в то время как
Защита в сам __ФАЙЛ__
определены? модуль супер __ЛИНИЯ__

Вот документ в рубине

«Здесь документ» относится к строкам из нескольких строк. После << вы можете указать строку или идентификатор для завершения строкового литерала, и все строки, следующие за текущей строкой до терминатора, являются значением строки.

Если терминатор заключен в кавычки, тип кавычек определяет тип строкового литерала, ориентированного на строку. Обратите внимание, что между << и терминатором не должно быть пробела.

Вот разные примеры –

Live Demo

#!/usr/bin/ruby -w

print <<EOF
   This is the first way of creating
   here document ie. multiple line string.
EOF

print <<"EOF";                # same as above
   This is the second way of creating
   here document ie. multiple line string.
EOF

print <<`EOC`                 # execute commands
	echo hi there
	echo lo there
EOC

print <<"foo", <<"bar"  # you can stack them
	I said foo.
foo
	I said bar.
bar

Это даст следующий результат –

   This is the first way of creating
   her document ie. multiple line string.
   This is the second way of creating
   her document ie. multiple line string.
hi there
lo there
      I said foo.
      I said bar.

Рубин НАЧАТЬ

Синтаксис

BEGIN {
   code
}

Объявляет код, который будет вызван перед запуском программы.

пример

Live Demo

#!/usr/bin/ruby

puts "This is main Ruby Program"

BEGIN {
   puts "Initializing Ruby Program"
}

Это даст следующий результат –

Initializing Ruby Program
This is main Ruby Program

Ruby END Заявление

Синтаксис

END {
   code
}

Объявляет код, который будет вызван в конце программы.

пример

Live Demo

#!/usr/bin/ruby

puts "This is main Ruby Program"

END {
   puts "Terminating Ruby Program"
}
BEGIN {
   puts "Initializing Ruby Program"
}

Это даст следующий результат –

Initializing Ruby Program
This is main Ruby Program
Terminating Ruby Program

Руби Комментарии

Комментарий скрывает строку, часть строки или несколько строк от интерпретатора Ruby. Вы можете использовать хеш-символ (#) в начале строки –

# I am a comment. Just ignore me.

Или комментарий может быть в той же строке после утверждения или выражения –

name = "Madisetti" # This is again comment

Вы можете прокомментировать несколько строк следующим образом –

# This is a comment.
# This is a comment, too.
# This is a comment, too.
# I said that already.

Вот другая форма. Этот блочный комментарий скрывает несколько строк от интерпретатора с = begin / = end –

=begin
This is a comment.
This is a comment, too.
This is a comment, too.
I said that already.
=end

Рубин – Классы и Объекты

Ruby – это идеальный объектно-ориентированный язык программирования. Особенности объектно-ориентированного языка программирования включают в себя –

  • Инкапсуляция данных
  • Абстракция данных
  • Полиморфизм
  • наследование

Эти функции обсуждались в главе « Объектно-ориентированный рубин» .

Объектно-ориентированная программа включает в себя классы и объекты. Класс – это проект, из которого создаются отдельные объекты. В объектно-ориентированных терминах мы говорим, что ваш велосипед является экземпляром класса объектов, известных как велосипеды.

Возьмите пример любого транспортного средства. Он включает в себя колеса, лошадиные силы и емкость топливного или бензобака. Эти характеристики формируют данные членов класса Vehicle. С помощью этих характеристик вы можете отличить одно транспортное средство от другого.

Транспортное средство также может иметь определенные функции, такие как остановка, вождение и превышение скорости. Даже эти функции образуют данные членов класса Vehicle. Следовательно, вы можете определить класс как комбинацию характеристик и функций.

Класс транспортного средства может быть определен как –

Class Vehicle {

   Number no_of_wheels
   Number horsepower
   Characters type_of_tank
   Number Capacity
   Function speeding {
   }
   
   Function driving {
   }
   
   Function halting {
   }
}

Назначая разные значения этим элементам данных, вы можете сформировать несколько экземпляров класса Vehicle. Например, самолет имеет три колеса, 1000 лошадиных сил, топливо в качестве типа танка и вместимость 100 литров. Точно так же автомобиль имеет четыре колеса, мощность 200 лошадиных сил, бензин в качестве типа бака и емкость 25 литров.

Определение класса в Ruby

Чтобы реализовать объектно-ориентированное программирование с использованием Ruby, вам сначала нужно научиться создавать объекты и классы в Ruby.

Класс в Ruby всегда начинается с ключевого слова class, за которым следует имя класса. Имя всегда должно быть в заглавных буквах. Класс Customer может отображаться как –

class Customer
end

Вы завершаете класс, используя ключевое слово end . Все члены данных в классе находятся между определением класса и ключевым словом end .

Переменные в классе Ruby

Ruby предоставляет четыре типа переменных –

  • Локальные переменные – локальные переменные – это переменные, которые определены в методе. Локальные переменные недоступны вне метода. Вы увидите более подробную информацию о методе в следующей главе. Локальные переменные начинаются со строчной буквы или _.

  • Переменные экземпляра – переменные экземпляра доступны в разных методах для любого конкретного экземпляра или объекта. Это означает, что переменные экземпляра меняются от объекта к объекту. Переменным экземпляра предшествует знак (@), за которым следует имя переменной.

  • Переменные класса – переменные класса доступны для разных объектов. Переменная класса принадлежит классу и является характеристикой класса. Им предшествует знак @@ и сопровождается именем переменной.

  • Глобальные переменные – переменные класса не доступны для разных классов. Если вы хотите иметь единственную переменную, которая доступна для всех классов, вам нужно определить глобальную переменную. Глобальным переменным всегда предшествует знак доллара ($).

Локальные переменные – локальные переменные – это переменные, которые определены в методе. Локальные переменные недоступны вне метода. Вы увидите более подробную информацию о методе в следующей главе. Локальные переменные начинаются со строчной буквы или _.

Переменные экземпляра – переменные экземпляра доступны в разных методах для любого конкретного экземпляра или объекта. Это означает, что переменные экземпляра меняются от объекта к объекту. Переменным экземпляра предшествует знак (@), за которым следует имя переменной.

Переменные класса – переменные класса доступны для разных объектов. Переменная класса принадлежит классу и является характеристикой класса. Им предшествует знак @@ и сопровождается именем переменной.

Глобальные переменные – переменные класса не доступны для разных классов. Если вы хотите иметь единственную переменную, которая доступна для всех классов, вам нужно определить глобальную переменную. Глобальным переменным всегда предшествует знак доллара ($).

пример

Используя переменную класса @@ no_of_customers, вы можете определить количество создаваемых объектов. Это позволяет при определении количества клиентов.

class Customer
   @@no_of_customers = 0
end

Создание объектов в Ruby с использованием нового метода

Объекты являются экземплярами класса. Теперь вы узнаете, как создавать объекты класса в Ruby. Вы можете создавать объекты в Ruby, используя метод new класса.

Метод new является уникальным типом метода, который предопределен в библиотеке Ruby. Новый метод принадлежит методам класса .

Вот пример для создания двух объектов cust1 и cust2 класса Customer –

cust1 = Customer. new
cust2 = Customer. new

Здесь cust1 и cust2 являются именами двух объектов. Вы пишете имя объекта, за которым следует знак равенства (=), после которого следует имя класса. Затем следует оператор точки и ключевое слово new .

Пользовательский метод для создания объектов Ruby

Вы можете передать параметры в метод new, и эти параметры можно использовать для инициализации переменных класса.

Когда вы планируете объявить новый метод с параметрами, вам нужно объявить метод initialize во время создания класса.

Метод initialize – это метод специального типа, который будет выполняться при вызове нового метода класса с параметрами.

Вот пример для создания метода инициализации –

class Customer
   @@no_of_customers = 0
   def initialize(id, name, addr)
      @cust_id = id
      @cust_name = name
      @cust_addr = addr
   end
end

В этом примере вы объявляете метод initialize с id, name и addr в качестве локальных переменных. Здесь def и end используются для определения инициализации метода Ruby. Вы узнаете больше о методах в следующих главах.

В методе initialize вы передаете значения этих локальных переменных в переменные экземпляра @cust_id, @cust_name и @cust_addr. Здесь локальные переменные содержат значения, которые передаются вместе с новым методом.

Теперь вы можете создавать объекты следующим образом –

cust1 = Customer.new("1", "John", "Wisdom Apartments, Ludhiya")
cust2 = Customer.new("2", "Poul", "New Empire road, Khandala")

Функции-члены в классе Ruby

В Ruby функции называются методами. Каждый метод в классе начинается с ключевого слова def, за которым следует имя метода.

Имя метода всегда предпочитается строчными буквами . Вы заканчиваете метод в Ruby, используя ключевое слово end .

Вот пример для определения метода Ruby –

class Sample
   def function
      statement 1
      statement 2
   end
end

Здесь оператор 1 и оператор 2 являются частью тела функции метода внутри класса Sample. Этими утверждениями могут быть любые допустимые операторы Ruby. Например, мы можем поместить метод put для печати Hello Ruby следующим образом:

class Sample
   def hello
      puts "Hello Ruby!"
   end
end

Теперь в следующем примере создайте один объект класса Sample и вызовите метод hello и посмотрите результат –

Live Demo

#!/usr/bin/ruby

class Sample
   def hello
      puts "Hello Ruby!"
   end
end

# Now using above class to create objects
object = Sample. new
object.hello

Это даст следующий результат –

Hello Ruby!

Простое тематическое исследование

Вот пример, если вы хотите больше практиковаться с классом и предметами.

Учебный пример Ruby Class

Ruby – переменные, константы и литералы

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

Ruby поддерживает пять типов переменных. Вы уже прошли небольшое описание этих переменных в предыдущей главе. Эти пять типов переменных описаны в этой главе.

Ruby Global Variables

Глобальные переменные начинаются с $. Неинициализированные глобальные переменные имеют значение nil и выдают предупреждения с опцией -w.

Присвоение глобальным переменным изменяет глобальный статус. Не рекомендуется использовать глобальные переменные. Они делают программы загадочными.

Вот пример, показывающий использование глобальной переменной.

Live Demo

#!/usr/bin/ruby

$global_variable = 10
class Class1
   def print_global
      puts "Global variable in Class1 is #$global_variable"
   end
end
class Class2
   def print_global
      puts "Global variable in Class2 is #$global_variable"
   end
end

class1obj = Class1.new
class1obj.print_global
class2obj = Class2.new
class2obj.print_global

Здесь $ global_variable является глобальной переменной. Это даст следующий результат –

ПРИМЕЧАНИЕ. – В Ruby вы МОЖЕТЕ получить доступ к значению любой переменной или константы, поставив символ хеша (#) непосредственно перед этой переменной или константой.

Global variable in Class1 is 10
Global variable in Class2 is 10

Переменные экземпляра Ruby

Переменные экземпляра начинаются с @. Неинициализированные переменные экземпляра имеют значение nil и выдают предупреждения с опцией -w.

Вот пример, показывающий использование переменных экземпляра.

Live Demo

#!/usr/bin/ruby

class Customer
   def initialize(id, name, addr)
      @cust_id = id
      @cust_name = name
      @cust_addr = addr
   end
   def display_details()
      puts "Customer id #@cust_id"
      puts "Customer name #@cust_name"
      puts "Customer address #@cust_addr"
   end
end

# Create Objects
cust1 = Customer.new("1", "John", "Wisdom Apartments, Ludhiya")
cust2 = Customer.new("2", "Poul", "New Empire road, Khandala")

# Call Methods
cust1.display_details()
cust2.display_details()

Здесь @cust_id, @cust_name и @cust_addr являются переменными экземпляра. Это даст следующий результат –

Customer id 1
Customer name John
Customer address Wisdom Apartments, Ludhiya
Customer id 2
Customer name Poul
Customer address New Empire road, Khandala

Переменные класса Ruby

Переменные класса начинаются с @@ и должны быть инициализированы, прежде чем их можно будет использовать в определениях методов.

Ссылка на неинициализированную переменную класса приводит к ошибке. Переменные класса являются общими для потомков класса или модуля, в котором определены переменные класса.

Переопределяющие переменные класса выдают предупреждения с опцией -w.

Вот пример, показывающий использование переменной класса –

Live Demo

#!/usr/bin/ruby

class Customer
   @@no_of_customers = 0
   def initialize(id, name, addr)
      @cust_id = id
      @cust_name = name
      @cust_addr = addr
   end
   def display_details()
      puts "Customer id #@cust_id"
      puts "Customer name #@cust_name"
      puts "Customer address #@cust_addr"
   end
   def total_no_of_customers()
      @@no_of_customers += 1
      puts "Total number of customers: #@@no_of_customers"
   end
end

# Create Objects
cust1 = Customer.new("1", "John", "Wisdom Apartments, Ludhiya")
cust2 = Customer.new("2", "Poul", "New Empire road, Khandala")

# Call Methods
cust1.total_no_of_customers()
cust2.total_no_of_customers()

Здесь @@ no_of_customers является переменной класса. Это даст следующий результат –

Total number of customers: 1
Total number of customers: 2

Ruby локальные переменные

Локальные переменные начинаются со строчной буквы или _. Область действия локальной переменной варьируется от класса, модуля, def или do до соответствующего конца или от открывающей фигурной скобки блока до закрывающей фигурной скобки {}.

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

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

В приведенном выше примере локальными переменными являются id, name и addr.

Рубиновые Константы

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

Константы не могут быть определены в методах. Ссылка на неинициализированную константу приводит к ошибке. Назначение константы, которая уже инициализирована, выдает предупреждение.

Live Demo

#!/usr/bin/ruby

class Example
   VAR1 = 100
   VAR2 = 200
   def show
      puts "Value of first Constant is #{VAR1}"
      puts "Value of second Constant is #{VAR2}"
   end
end

# Create Objects
object = Example.new()
object.show

Здесь VAR1 и VAR2 являются константами. Это даст следующий результат –

Value of first Constant is 100
Value of second Constant is 200

Ruby псевдопеременные

Это специальные переменные, которые имеют вид локальных переменных, но ведут себя как константы. Вы не можете присвоить какое-либо значение этим переменным.

  • self – объект получателя текущего метода.

  • true – значение, представляющее true.

  • false – значение, представляющее false.

  • nil – значение, представляющее неопределенное.

  • __FILE__ – Имя текущего исходного файла.

  • __LINE__ – Текущий номер строки в исходном файле.

self – объект получателя текущего метода.

true – значение, представляющее true.

false – значение, представляющее false.

nil – значение, представляющее неопределенное.

__FILE__ – Имя текущего исходного файла.

__LINE__ – Текущий номер строки в исходном файле.

Ruby Basic Literal

Правила, которые Ruby использует для литералов, просты и интуитивно понятны. Этот раздел объясняет все основные литералы Ruby.

Целые числа

Ruby поддерживает целые числа. Целое число может варьироваться от -2 30 до 2 30-1 или от -2 62 до 2 62-1 . Целые числа в этом диапазоне являются объектами класса Fixnum, а целые числа вне этого диапазона хранятся в объектах класса Bignum .

Вы пишете целые числа с использованием необязательного начального знака, необязательного базового индикатора (0 для восьмеричного, 0x для шестнадцатеричного или 0b для двоичного), за которым следует строка цифр в соответствующем основании. Символы подчеркивания игнорируются в строке цифр.

Вы также можете получить целочисленное значение, соответствующее символу ASCII, или экранировать последовательность, поставив перед ней знак вопроса.

пример

123                  # Fixnum decimal
1_234                # Fixnum decimal with underline
-500                 # Negative Fixnum
0377                 # octal
0xff                 # hexadecimal
0b1011               # binary
?a                   # character code for 'a'
?\n                  # code for a newline (0x0a)
12345678901234567890 # Bignum

ПРИМЕЧАНИЕ. – Класс и объекты объясняются в отдельной главе этого руководства.

Плавающие числа

Ruby поддерживает плавающие числа. Они также числа, но с десятичными знаками. Числа с плавающей точкой являются объектами класса Float и могут быть следующими:

пример

123.4                # floating point value
1.0e6                # scientific notation
4E20                 # dot not required
4e+20                # sign before exponential

Строковые литералы

Рубиновые строки – это просто последовательности 8-битных байтов, и они являются объектами класса String. Строки в двойных кавычках допускают подстановку и запись с обратной косой чертой, но строки в одинарных кавычках не допускают подстановку и допускают запись с обратной косой чертой только для \\ и \ ‘

пример

Live Demo

#!/usr/bin/ruby -w

puts 'escape using "\\"';
puts 'That\'s right';

Это даст следующий результат –

escape using "\"
That's right

Вы можете подставить значение любого выражения Ruby в строку, используя последовательность # {expr} . Здесь expr может быть любым выражением ruby.

Live Demo

#!/usr/bin/ruby -w

puts "Multiplication Value : #{24*60*60}";

Это даст следующий результат –

Multiplication Value : 86400

Нотация с обратной косой чертой

Ниже приведен список нотаций обратной косой черты, поддерживаемых Ruby –

нотация Персонаж представлен
\ п Новая строка (0x0a)
Возврат каретки (0x0d)
\ е Formfeed (0x0c)
\ б Backspace (0x08)
\ а Белл (0x07)
\ е Побег (0x1b)
\ s Пробел (0x20)
\ NNN Восьмеричное обозначение (n = 0-7)
\ Хпп Шестнадцатеричное обозначение (n от 0 до 9, af или AF)
\ cx, \ Cx Контроль-х
\ Mx Мета-х (c | 0x80)
\ M- \ Cx Meta-Control-х
\Икс Персонаж х

Для более подробной информации о Ruby Strings, перейдите через Ruby Strings .

Ruby Arrays

Литералы Ruby Array создаются путем размещения разделенных запятыми серий ссылок на объекты между квадратными скобками. Завершающая запятая игнорируется.

пример

Live Demo

#!/usr/bin/ruby

ary = [  "fred", 10, 3.14, "This is a string", "last element", ]
ary.each do |i|
   puts i
end

Это даст следующий результат –

fred
10
3.14
This is a string
last element

Для более подробной информации о Ruby Arrays, перейдите через Ruby Arrays .

Рубиновые Хэши

Литеральный хэш Ruby создается путем размещения списка пар ключ / значение между фигурными скобками, с запятой или последовательностью => между ключом и значением. Завершающая запятая игнорируется.

пример

Live Demo

#!/usr/bin/ruby

hsh = colors = { "red" => 0xf00, "green" => 0x0f0, "blue" => 0x00f }
hsh.each do |key, value|
   print key, " is ", value, "\n"
end

Это даст следующий результат –

red is 3840
green is 240
blue is 15

Для более подробной информации о Ruby Hashes, перейдите через Ruby Hashes .

Рубиновые диапазоны

Диапазон представляет интервал, который представляет собой набор значений с началом и концом. Диапазоны могут быть созданы с использованием литералов s..e и s … e или Range.new.

Диапазоны, построенные с использованием .., запускаются от начала до конца включительно. Те, которые созданы с использованием … исключают конечное значение. При использовании в качестве итератора диапазоны возвращают каждое значение в последовательности.

Диапазон (1..5) означает, что он включает в себя 1, 2, 3, 4, 5 значений, а диапазон (1 … 5) означает, что он включает в себя 1, 2, 3, 4 значения.

пример

Live Demo

#!/usr/bin/ruby

(10..15).each do |n| 
   print n, ' ' 
end

Это даст следующий результат –

10 11 12 13 14 15

Для более подробной информации о Ruby Ranges, пройдите через Ruby Ranges .

Руби – Операторы

Ruby поддерживает широкий набор операторов, как и следовало ожидать от современного языка. Большинство операторов на самом деле являются вызовами методов. Например, a + b интерпретируется как a. + (B), где метод + в объекте, на который ссылается переменная a, вызывается с b в качестве аргумента.

Для каждого оператора (+ – * /% ** & | ^ << >> && ||) существует соответствующая форма сокращенного оператора присваивания (+ = – = и т. Д.).

Рубиновые арифметические операторы

Предположим, что переменная a содержит 10, а переменная b содержит 20, тогда –

оператор Описание пример
+ Добавление – добавляет значения по обе стороны от оператора. а + б даст 30
Вычитание – вычитает правый операнд из левого операнда. а – б даст -10
* Умножение – Умножает значения по обе стороны от оператора. а * б даст 200
/ Деление – делит левый операнд на правый. б / у даст 2
% Модуль – Делит левый операнд на правый операнд и возвращает остаток. б% а даст 0
** Экспонент – Выполняет экспоненциальный (силовой) расчет операторов. а ** б даст 10 к силе 20

Операторы сравнения Ruby

Предположим, что переменная a содержит 10, а переменная b содержит 20, тогда –

оператор Описание пример
== Проверяет, равны ли значения двух операндов или нет, если да, тогда условие становится истинным. (a == b) не соответствует действительности.
знак равно Проверяет, равны ли значения двух операндов или нет, если значения не равны, тогда условие становится истинным. (a! = b) верно.
> Проверяет, больше ли значение левого операнда, чем значение правого операнда, если да, тогда условие становится истинным. (а> б) не соответствует действительности.
< Проверяет, меньше ли значение левого операнда, чем значение правого операнда, если да, тогда условие становится истинным. (а <б) верно.
> = Проверяет, больше ли значение левого операнда или равно значению правого операнда, если да, тогда условие становится истинным. (a> = b) не соответствует действительности.
<= Проверяет, меньше ли значение левого операнда или равно значению правого операнда, если да, тогда условие становится истинным. (a <= b) верно.
<=> Комбинированный оператор сравнения. Возвращает 0, если первый операнд равен второму, 1, если первый операнд больше второго, и -1, если первый операнд меньше второго. (<=> б) возвращает -1.
=== Используется для проверки равенства в предложении when оператора case . (1 … 10) === 5 возвращает true.
.eql? True, если получатель и аргумент имеют одинаковый тип и одинаковые значения. 1 == 1.0 возвращает true, а 1.eql? (1.0) – false.
равны? True, если получатель и аргумент имеют одинаковый идентификатор объекта. если aObj является дубликатом bObj, то aObj == bObj имеет значение true, a.equal? ​​bObj имеет значение false, а a.equal? ​​aObj имеет значение true.

Операторы присваивания Ruby

Предположим, что переменная a содержит 10, а переменная b содержит 20, тогда –

оператор Описание пример
знак равно Простой оператор присваивания, присваивает значения из правого операнда левому операнду. c = a + b назначит значение a + b в c
+ = Добавить оператор присваивания AND, добавляет правый операнд в левый операнд и присваивает результат левому операнду. с + = а эквивалентно с = с + а
знак равно Вычитание И оператор присваивания, вычитает правый операнд из левого операнда и присваивает результат левому операнду. с – = а эквивалентно с = с – а
знак равно Оператор присваивания умножения И, умножает правый операнд на левый операнд и присваивает результат левому операнду. с * = а эквивалентно с = с * а
знак равно Оператор деления И присваивания, делит левый операнд на правый операнд и присваивает результат левому операнду. с / = а эквивалентно с = с / а
знак равно Оператор присваивания модуля И, принимает модуль с использованием двух операндов и присваивает результат левому операнду. с% = а эквивалентно с = с% а
знак равно Оператор присваивания экспоненты AND выполняет экспоненциальный (силовой) расчет операторов и присваивает значение левому операнду. с ** = а эквивалентно с = с ** а

Ruby Parallel Assignment

Ruby также поддерживает параллельное назначение переменных. Это позволяет инициализировать несколько переменных одной строкой кода Ruby. Например –

a = 10
b = 20
c = 30

Это может быть объявлено быстрее с использованием параллельного присваивания –

a, b, c = 10, 20, 30

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

a, b = b, c

Рубиновые побитовые операторы

Побитовый оператор работает с битами и выполняет побитовую операцию.

Предположим, если а = 60; и б = 13; теперь в двоичном формате они будут выглядеть следующим образом –

 a    =  0011 1100
 b    =  0000 1101
 ------------------
 a&b  =  0000 1100
 a|b  =  0011 1101
 a^b  =  0011 0001
 ~a   =  1100 0011

Следующие побитовые операторы поддерживаются языком Ruby.

оператор Описание пример
& Двоичный оператор AND немного копирует результат, если он существует в обоих операндах. (a & b) даст 12, что составляет 0000 1100
| Оператор двоичного ИЛИ копирует немного, если он существует в любом из операндов. (a | b) даст 61, что составляет 0011 1101
^ Двоичный оператор XOR копирует бит, если он установлен в одном операнде, но не в обоих. (a ^ b) даст 49, что составляет 0011 0001
~ Оператор дополнения двоичных единиц является унарным и имеет эффект «переворачивания» битов. (~ a) даст -61, что составляет 1100 0011 в форме дополнения 2 из-за двоичного числа со знаком.
<< Двоичный оператор левого сдвига. Значение левого операнда перемещается влево на количество битов, указанное правым операндом. << 2 даст 240, что составляет 1111 0000
>> Оператор двоичного правого сдвига. Значение левого операнда перемещается вправо на количество битов, указанное правым операндом. a >> 2 даст 15, что составляет 0000 1111

Рубиновые логические операторы

Следующие логические операторы поддерживаются языком Ruby

Предположим, что переменная a содержит 10, а переменная b содержит 20, тогда –

оператор Описание пример
а также Называется логический оператор И. Если оба операнда верны, то условие становится истинным. (а и б) верно.
или же Вызывается логическим оператором ИЛИ. Если любой из двух операндов отличен от нуля, условие становится истинным. (а или б) верно.
&& Называется логический оператор И. Если оба операнда отличны от нуля, условие становится истинным. (a && b) верно.
|| Вызывается логическим оператором ИЛИ. Если любой из двух операндов отличен от нуля, условие становится истинным. (a || b) верно.
! Вызывается логическим оператором НЕ. Используйте для изменения логического состояния своего операнда. Если условие истинно, то оператор Логический НЕ будет делать ложь. ! (a && b) ложно.
не Вызывается логическим оператором НЕ. Используйте для изменения логического состояния своего операнда. Если условие истинно, то оператор Логический НЕ будет делать ложь. не (a && b) является ложным.

Рубин Тернарный Оператор

Еще один оператор называется Ternary Operator. Сначала он оценивает выражение для истинного или ложного значения, а затем выполняет одно из двух заданных утверждений в зависимости от результата оценки. Условный оператор имеет такой синтаксис –

оператор Описание пример
? : Условное выражение Если условие верно? Тогда значение X: в противном случае значение Y

Операторы Рубинового Диапазона

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

В Ruby эти последовательности создаются с использованием операторов диапазона «..» и «…». Форма с двумя точками создает включающий диапазон, а форма с тремя точками создает диапазон, который исключает указанное высокое значение.

оператор Описание пример
.. Создает диапазон от начальной точки до конечной точки включительно. 1..10 Создает диапазон от 1 до 10 включительно.
Создает диапазон от начальной точки до эксклюзивной конечной точки. 1 … 10 Создает диапазон от 1 до 9.

Рубин определен? операторы

определены? это специальный оператор, который принимает форму вызова метода, чтобы определить, определено ли переданное выражение. Возвращает строку описания выражения или nil, если выражение не определено.

Есть различное использование определенных? оператор

Использование 1

defined? variable # True if variable is initialized

Например

foo = 42
defined? foo    # => "local-variable"
defined? $_     # => "global-variable"
defined? bar    # => nil (undefined)

Использование 2

defined? method_call # True if a method is defined

Например

defined? puts        # => "method"
defined? puts(bar)   # => nil (bar is not defined here)
defined? unpack      # => nil (not defined here)

Использование 3

# True if a method exists that can be called with super user
defined? super

Например

defined? super     # => "super" (if it can be called)
defined? super     # => nil (if it cannot be)

Использование 4

defined? yield   # True if a code block has been passed

Например

defined? yield    # => "yield" (if there is a block passed)
defined? yield    # => nil (if there is no block)

Руби Дот “.” и двойные двоеточия “::” Операторы

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

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

Помните, в Ruby классы и методы тоже можно считать константами.

Вам просто нужно добавить префикс :: Const_name к выражению, которое возвращает соответствующий класс или объект модуля.

Если префиксное выражение не используется, основной класс Object используется по умолчанию.

Вот два примера –

MR_COUNT = 0         # constant defined on main Object class
module Foo
   MR_COUNT = 0
   ::MR_COUNT = 1    # set global count to 1
   MR_COUNT = 2      # set local count to 2
end
puts MR_COUNT        # this is the global constant
puts Foo::MR_COUNT   # this is the local "Foo" constant

Второй пример

CONST = ' out there'
class Inside_one
   CONST = proc {' in there'}
   def where_is_my_CONST
      ::CONST + ' inside one'
   end
end
class Inside_two
   CONST = ' inside two'
   def where_is_my_CONST
      CONST
   end
end
puts Inside_one.new.where_is_my_CONST
puts Inside_two.new.where_is_my_CONST
puts Object::CONST + Inside_two::CONST
puts Inside_two::CONST + CONST
puts Inside_one::CONST
puts Inside_one::CONST.call + Inside_two::CONST

Приоритет операторов Ruby

В следующей таблице перечислены все операторы от наивысшего приоритета к низшему.

метод оператор Описание
да :: Оператор с постоянным разрешением
да знак равно Ссылка на элемент, набор элементов
да ** Возведение в степень (возведение к власти)
да ! ~ + – Не, дополнение, унарный плюс и минус (имена методов для двух последних: + @ и – @)
да * /% Умножить, разделить и по модулю
да + – Сложение и вычитание
да >> << Сдвиг вправо и влево
да & Побитовое И
да ^ | Побитовое исключающее `ИЛИ ‘и регулярное` ИЛИ’
да <= <>> = Операторы сравнения
да <=> == ===! = = ~! ~ Операторы равенства и сопоставления с образцом (! = И! ~ Не могут быть определены как методы)
&& Логическое «И»
|| Логическое «ИЛИ»
.. … Ассортимент (включительно и эксклюзивно)
? : Троичный если-то-еще
=% = {/ = – = + = | = & = >> = << = * = && = || = ** = присваивание
определены? Проверьте, определен ли указанный символ
не Логическое отрицание
или и Логическая композиция

ПРИМЕЧАНИЕ. – Операторы, для которых в столбце «метод» указано « Да», на самом деле являются методами и могут быть переопределены.

Рубин – Комментарии

Комментарии – это строки комментариев в коде Ruby, которые игнорируются во время выполнения. Однострочный комментарий начинается с символа # и продолжается от # до конца строки следующим образом:

Live Demo

#!/usr/bin/ruby -w
# This is a single line comment.

puts "Hello, Ruby!"

При выполнении вышеуказанная программа дает следующий результат –

Hello, Ruby!

Ruby Multiline Комментарии

Вы можете комментировать несколько строк, используя синтаксис = begin и = end следующим образом:

Live Demo

#!/usr/bin/ruby -w

puts "Hello, Ruby!"

=begin
This is a multiline comment and con spwan as many lines as you
like. But =begin and =end should come in the first line only. 
=end

При выполнении вышеуказанная программа дает следующий результат –

Hello, Ruby!

Убедитесь, что конечные комментарии достаточно далеки от кода и их легко отличить. Если в блоке существует более одного завершающего комментария, выровняйте их. Например –

@counter      # keeps track times page has been hit
@siteCounter  # keeps track of times all pages have been hit

Руби – если … еще, случай, если

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

Ruby if … else Заявление

Синтаксис

if conditional [then]
   code...
[elsif conditional [then]
   code...]...
[else
   code...]
end

если выражения используются для условного исполнения. Значения false и nil – false, а все остальное – true. Обратите внимание, что Руби использует elsif, а не иначе, как и elif.

Выполняет код, если условие истинно. Если условие не истинно, выполняется код, указанный в предложении else.

Условное выражение if отделяется от кода зарезервированным словом then , новой строкой или точкой с запятой.

пример

Live Demo

#!/usr/bin/ruby

x = 1
if x > 2
   puts "x is greater than 2"
elsif x <= 2 and x!=0
   puts "x is 1"
else
   puts "I can't guess the number"
end
x is 1

Руби если модификатор

Синтаксис

code if condition

Выполняет код, если условие истинно.

пример

Live Demo

#!/usr/bin/ruby

$debug = 1
print "debug\n" if $debug

Это даст следующий результат –

debug

Рубин если Заявление

Синтаксис

unless conditional [then]
   code
[else
   code ]
end

Выполняет код, если условие ложно. Если условие истинно, выполняется код, указанный в предложении else.

пример

Live Demo

#!/usr/bin/ruby

x = 1 
unless x>=2
   puts "x is less than 2"
 else
   puts "x is greater than 2"
end

Это даст следующий результат –

x is less than 2

Руби, если модификатор

Синтаксис

code unless conditional

Выполняет код, если условие ложно.

пример

Live Demo

#!/usr/bin/ruby

$var =  1
print "1 -- Value is set\n" if $var
print "2 -- Value is set\n" unless $var

$var = false
print "3 -- Value is set\n" unless $var

Это даст следующий результат –

1 -- Value is set
3 -- Value is set

Рубиновый кейс

Синтаксис

case expression
[when expression [, expression ...] [then]
   code ]...
[else
   code ]
end

Сравнивает выражение, заданное регистром, и выражение , указанное при использовании оператора ===, и выполняет код соответствующего предложения when.

Выражение, указанное в предложении when, оценивается как левый операнд. Если нет, когда совпадают предложения, case выполняет код предложения else .

Выражение оператора when отделено от кода зарезервированным словом then, новой строкой или точкой с запятой. Таким образом –

case expr0
when expr1, expr2
   stmt1
when expr3, expr4
   stmt2
else
   stmt3
end

в основном похож на следующее –

_tmp = expr0
if expr1 === _tmp || expr2 === _tmp
   stmt1
elsif expr3 === _tmp || expr4 === _tmp
   stmt2
else
   stmt3
end

пример

Live Demo

#!/usr/bin/ruby

$age =  5
case $age
when 0 .. 2
   puts "baby"
when 3 .. 6
   puts "little child"
when 7 .. 12
   puts "child"
when 13 .. 18
   puts "youth"
else
   puts "adult"
end

Это даст следующий результат –

little child

Рубин – Петли

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

Рубиновый оператор

Синтаксис

while conditional [do]
   code
end

Выполняет код, пока условное истинно. Условный цикл while отделяется от кода зарезервированным словом do, символом новой строки, обратной косой чертой \ или точкой с запятой;.

пример

Live Demo

#!/usr/bin/ruby

$i = 0
$num = 5

while $i < $num  do
   puts("Inside the loop i = #$i" )
   $i +=1
end

Это даст следующий результат –

Inside the loop i = 0
Inside the loop i = 1
Inside the loop i = 2
Inside the loop i = 3
Inside the loop i = 4

Рубиновый модификатор

Синтаксис

code while condition

OR

begin 
  code 
end while conditional

Выполняет код, пока условное истинно.

Если модификатор while следует за оператором begin без выражений восстановления или проверки, код выполняется один раз перед оценкой условия.

пример

Live Demo

#!/usr/bin/ruby

$i = 0
$num = 5
begin
   puts("Inside the loop i = #$i" )
   $i +=1
end while $i < $num

Это даст следующий результат –

Inside the loop i = 0
Inside the loop i = 1
Inside the loop i = 2
Inside the loop i = 3
Inside the loop i = 4

Рубин до Заявления

until conditional [do]
   code
end

Выполняет код, в то время как условный ложный. Условный оператор до отделяется от кода зарезервированным словом do , новой строкой или точкой с запятой.

пример

Live Demo

#!/usr/bin/ruby

$i = 0
$num = 5

until $i > $num  do
   puts("Inside the loop i = #$i" )
   $i +=1;
end

Это даст следующий результат –

Inside the loop i = 0
Inside the loop i = 1
Inside the loop i = 2
Inside the loop i = 3
Inside the loop i = 4
Inside the loop i = 5

Руби до модификатора

Синтаксис

code until conditional

OR

begin
   code
end until conditional

Выполняет код, в то время как условный ложный.

Если модификатор before следует за оператором begin без предложений спасения или обеспечения, код выполняется один раз перед оценкой условия .

пример

Live Demo

#!/usr/bin/ruby

$i = 0
$num = 5
begin
   puts("Inside the loop i = #$i" )
   $i +=1;
end until $i > $num

Это даст следующий результат –

Inside the loop i = 0
Inside the loop i = 1
Inside the loop i = 2
Inside the loop i = 3
Inside the loop i = 4
Inside the loop i = 5

Рубин для Заявления

Синтаксис

for variable [, variable ...] in expression [do]
   code
end

Выполняет код один раз для каждого элемента в выражении .

пример

Live Demo

#!/usr/bin/ruby

for i in 0..5
   puts "Value of local variable is #{i}"
end

Здесь мы определили диапазон 0..5. Утверждение для i в 0..5 позволит i принимать значения в диапазоне от 0 до 5 (включая 5). Это даст следующий результат –

Value of local variable is 0
Value of local variable is 1
Value of local variable is 2
Value of local variable is 3
Value of local variable is 4
Value of local variable is 5

Цикл for … in почти в точности эквивалентен следующему:

(expression).each do |variable[, variable...]| code end

за исключением того, что цикл for не создает новую область видимости для локальных переменных. Выражение цикла for отделяется от кода зарезервированным словом do, новой строкой или точкой с запятой.

пример

Live Demo

#!/usr/bin/ruby

(0..5).each do |i|
   puts "Value of local variable is #{i}"
end

Это даст следующий результат –

Value of local variable is 0
Value of local variable is 1
Value of local variable is 2
Value of local variable is 3
Value of local variable is 4
Value of local variable is 5

Ruby Break Заявление

Синтаксис

break

Завершает самый внутренний цикл. Завершает метод со связанным блоком, если вызван в блоке (с методом, возвращающим ноль).

пример

Live Demo

#!/usr/bin/ruby

for i in 0..5
   if i > 2 then
      break
   end
   puts "Value of local variable is #{i}"
end

Это даст следующий результат –

Value of local variable is 0
Value of local variable is 1
Value of local variable is 2

Ruby следующее заявление

Синтаксис

next

Переходит к следующей итерации самого внутреннего цикла. Завершает выполнение блока, если он вызывается внутри блока (с yield или call, возвращающим ноль).

пример

Live Demo

#!/usr/bin/ruby

for i in 0..5
   if i < 2 then
      next
   end
   puts "Value of local variable is #{i}"
end

Это даст следующий результат –

Value of local variable is 2
Value of local variable is 3
Value of local variable is 4
Value of local variable is 5

Ruby Redo Заявление

Синтаксис

redo

Перезапускает эту итерацию самого внутреннего цикла без проверки состояния цикла. Перезапускает yield или call, если вызывается в блоке.

пример

#!/usr/bin/ruby

for i in 0..5
   if i < 2 then
      puts "Value of local variable is #{i}"
      redo
   end
end

Это даст следующий результат и будет идти в бесконечном цикле –

Value of local variable is 0
Value of local variable is 0
............................

Заявление о повторных попытках Ruby

Синтаксис

retry

Если повторная попытка появляется в предложении спасения выражения начала, перезапустите с начала тела начала.

begin
   do_something # exception raised
rescue
   # handles error
   retry  # restart from beginning
end

Если в итераторе появляется повтор, блок или тело выражения for перезапускает вызов вызова итератора. Аргументы к итератору переоцениваются.

for i in 1..5
   retry if some_condition # restart from i == 1
end

пример

#!/usr/bin/ruby
for i in 0..5
   retry if i > 2
puts "Value of local variable is #{i}"
end

Это даст следующий результат и будет идти в бесконечном цикле –

Value of local variable is 1
Value of local variable is 2
Value of local variable is 1
Value of local variable is 2
Value of local variable is 1
Value of local variable is 2
............................

Рубин – Методы

Методы Ruby очень похожи на функции в любом другом языке программирования. Методы Ruby используются для объединения одного или нескольких повторяющихся операторов в один блок.

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

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

Синтаксис

def method_name [( [arg [= default]]...[, * arg [, &expr ]])]
   expr..
end

Итак, вы можете определить простой метод следующим образом:

def method_name 
   expr..
end

Вы можете представить метод, который принимает параметры, подобные этим –

def method_name (var1, var2)
   expr..
end

Вы можете установить значения по умолчанию для параметров, которые будут использоваться, если метод вызывается без передачи необходимых параметров –

def method_name (var1 = value1, var2 = value2)
   expr..
end

Каждый раз, когда вы вызываете простой метод, вы пишете только имя метода следующим образом:

method_name

Однако, когда вы вызываете метод с параметрами, вы пишете имя метода вместе с параметрами, такими как –

method_name 25, 30

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

пример

Live Demo

#!/usr/bin/ruby

def test(a1 = "Ruby", a2 = "Perl")
   puts "The programming language is #{a1}"
   puts "The programming language is #{a2}"
end
test "C", "C++"
test

Это даст следующий результат –

The programming language is C
The programming language is C++
The programming language is Ruby
The programming language is Perl

Возвращаемые значения из методов

Каждый метод в Ruby возвращает значение по умолчанию. Это возвращаемое значение будет значением последнего оператора. Например –

def test
   i = 100
   j = 10
   k = 0
end

Этот метод при вызове вернет последнюю объявленную переменную k .

Ruby заявление о возврате

Оператор return в ruby ​​используется для возврата одного или нескольких значений из метода Ruby.

Синтаксис

return [expr[`,' expr...]]

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

пример

return

OR

return 12

OR

return 1,2,3

Посмотрите на этот пример –

Live Demo

#!/usr/bin/ruby

def test
   i = 100
   j = 200
   k = 300
return i, j, k
end
var = test
puts var

Это даст следующий результат –

100
200
300

Переменное количество параметров

Предположим, вы объявляете метод, который принимает два параметра, всякий раз, когда вы вызываете этот метод, вам необходимо передать два параметра вместе с ним.

Тем не менее, Ruby позволяет объявлять методы, которые работают с переменным числом параметров. Давайте рассмотрим образец этого –

Live Demo

#!/usr/bin/ruby

def sample (*test)
   puts "The number of parameters is #{test.length}"
   for i in 0...test.length
      puts "The parameters are #{test[i]}"
   end
end
sample "Zara", "6", "F"
sample "Mac", "36", "M", "MCA"

В этом коде вы объявили образец метода, который принимает тест одного параметра. Однако этот параметр является переменным параметром. Это означает, что этот параметр может принимать любое количество переменных. Итак, приведенный выше код даст следующий результат –

The number of parameters is 3
The parameters are Zara
The parameters are 6
The parameters are F
The number of parameters is 4
The parameters are Mac
The parameters are 36
The parameters are M
The parameters are MCA

Методы класса

Если метод определен вне определения класса, метод помечается как закрытый по умолчанию. С другой стороны, методы, определенные в определении класса, по умолчанию помечены как общедоступные. Видимость по умолчанию и приватная метка методов могут быть изменены как публичными, так и приватными в модуле.

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

Ruby дает вам способ получить доступ к методу без создания экземпляра класса. Давайте посмотрим, как метод класса объявлен и доступен –

class Accounts
   def reading_charge
   end
   def Accounts.return_date
   end
end

Посмотрите, как объявлен метод return_date. Он объявляется с именем класса, за которым следует точка, за которой следует имя метода. Вы можете получить доступ к этому методу класса напрямую следующим образом:

Accounts.return_date

Чтобы получить доступ к этому методу, вам не нужно создавать объекты класса Accounts.

Заявление псевдонима Ruby

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

Создание псевдонимов для пронумерованных глобальных переменных ($ 1, $ 2, …) запрещено. Переопределение встроенных глобальных переменных может вызвать серьезные проблемы.

Синтаксис

alias method-name method-name
alias global-variable-name global-variable-name

пример

alias foo bar
alias $MATCH $&

Здесь мы определили псевдоним foo для bar, а $ MATCH – это псевдоним для $ &

Ruby undef Заявление

Это отменяет определение метода. Undef не может появиться в теле метода.

Используя undef и псевдоним , интерфейс класса может быть изменен независимо от суперкласса, но обратите внимание, что он может нарушать работу программ внутренним вызовом метода self.

Синтаксис

undef method-name

пример

Чтобы отменить определение метода с именем bar, сделайте следующее:

undef bar

Рубин – Блоки

Вы видели, как Ruby определяет методы, в которые можно поместить число операторов, а затем вы вызываете этот метод. Точно так же в Ruby есть концепция Block.

  • Блок состоит из кусков кода.

  • Вы назначаете имя для блока.

  • Код в блоке всегда заключен в фигурные скобки ({}).

  • Блок всегда вызывается из функции с тем же именем, что и у блока. Это означает, что если у вас есть блок с именем test , то вы используете функциональный тест для вызова этого блока.

  • Вы вызываете блок с помощью оператора yield .

Блок состоит из кусков кода.

Вы назначаете имя для блока.

Код в блоке всегда заключен в фигурные скобки ({}).

Блок всегда вызывается из функции с тем же именем, что и у блока. Это означает, что если у вас есть блок с именем test , то вы используете функциональный тест для вызова этого блока.

Вы вызываете блок с помощью оператора yield .

Синтаксис

block_name {
   statement1
   statement2
   ..........
}

Здесь вы научитесь вызывать блок с помощью простого оператора yield . Вы также научитесь использовать оператор yield с параметрами для вызова блока. Вы проверите пример кода с обоими типами операторов yield .

Отчет о доходности

Давайте посмотрим на пример выражения yield –

Live Demo

#!/usr/bin/ruby

def test
   puts "You are in the method"
   yield
   puts "You are again back to the method"
   yield
end
test {puts "You are in the block"}

Это даст следующий результат –

You are in the method
You are in the block
You are again back to the method
You are in the block

Вы также можете передать параметры с помощью оператора yield. Вот пример –

Live Demo

#!/usr/bin/ruby

def test
   yield 5
   puts "You are in the method test"
   yield 100
end
test {|i| puts "You are in the block #{i}"}

Это даст следующий результат –

You are in the block 5
You are in the method test
You are in the block 100

Здесь написано выражение выхода с параметрами. Вы даже можете передать более одного параметра. В блоке вы помещаете переменную между двумя вертикальными линиями (||), чтобы принять параметры. Следовательно, в предыдущем коде оператор yield 5 передает значение 5 в качестве параметра в тестовый блок.

Теперь посмотрим на следующее утверждение –

test {|i| puts "You are in the block #{i}"}

Здесь значение 5 принимается в переменной i . Теперь соблюдайте следующее утверждение о путях:

puts "You are in the block #{i}"

Вывод этого оператора put

You are in the block 5

Если вы хотите передать более одного параметра, то оператор yield становится:

yield a, b

и блок –

test {|a, b| statement}

Параметры будут разделены запятыми.

Блоки и методы

Вы видели, как блок и метод могут быть связаны друг с другом. Обычно вы вызываете блок, используя оператор yield из метода, имя которого совпадает с именем блока. Поэтому ты пишешь –

Live Demo

#!/usr/bin/ruby

def test
   yield
end
test{ puts "Hello world"}

Этот пример – самый простой способ реализовать блок. Вы вызываете тестовый блок с помощью оператора yield .

Но если последнему аргументу метода предшествует &, тогда вы можете передать блок этому методу, и этот блок будет присвоен последнему параметру. Если в списке аргументов есть и *, и &, то & должно появиться позже.

Live Demo

#!/usr/bin/ruby

def test(&block)
   block.call
end
test { puts "Hello World!"}

Это даст следующий результат –

Hello World!

Начало и конец блоков

Каждый исходный файл Ruby может объявлять блоки кода, которые будут выполняться во время загрузки файла (блоки BEGIN) и после завершения программы (блоки END).

Live Demo

#!/usr/bin/ruby

BEGIN { 
   # BEGIN block code 
   puts "BEGIN code block"
} 

END { 
   # END block code 
   puts "END code block"
}
   # MAIN block code 
puts "MAIN code block"

Программа может включать несколько блоков BEGIN и END. Начальные блоки выполняются в том порядке, в котором они встречаются. Блоки END выполняются в обратном порядке. При выполнении вышеуказанная программа дает следующий результат –

BEGIN code block
MAIN code block
END code block

Ruby – Модули и Миксины

Модули – это способ группировки методов, классов и констант. Модули дают вам два основных преимущества.

  • Модули обеспечивают пространство имен и предотвращают конфликты имен .

  • Модули реализуют смешанный механизм.

Модули обеспечивают пространство имен и предотвращают конфликты имен .

Модули реализуют смешанный механизм.

Модули определяют пространство имен, «песочницу», в которую могут играть ваши методы и константы, не беспокоясь о том, что на них будут воздействовать другие методы и константы.

Синтаксис

module Identifier
   statement1
   statement2
   ...........
end

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

Как и в случае с методами класса, вы вызываете метод модуля, добавляя перед его именем имя модуля и точку, и ссылаетесь на константу, используя имя модуля и два двоеточия.

пример

#!/usr/bin/ruby

# Module defined in trig.rb file

module Trig
   PI = 3.141592654
   def Trig.sin(x)
   # ..
   end
   def Trig.cos(x)
   # ..
   end
end

Мы можем определить еще один модуль с тем же именем функции, но с другой функциональностью –

#!/usr/bin/ruby

# Module defined in moral.rb file

module Moral
   VERY_BAD = 0
   BAD = 1
   def Moral.sin(badness)
   # ...
   end
end

Как и методы класса, всякий раз, когда вы определяете метод в модуле, вы указываете имя модуля, за которым следует точка, а затем имя метода.

Ruby требует утверждения

Оператор require похож на оператор include языка C и C ++ и оператор импорта Java. Если третья программа хочет использовать какой-либо определенный модуль, она может просто загрузить файлы модуля, используя оператор Ruby require

Синтаксис

require filename

Здесь не обязательно указывать расширение .rb вместе с именем файла.

пример

$LOAD_PATH << '.'

require 'trig.rb'
require 'moral'

y = Trig.sin(Trig::PI/4)
wrongdoing = Moral.sin(Moral::VERY_BAD)

Здесь мы используем $ LOAD_PATH << ‘.’ чтобы Ruby знал, что включенные файлы должны быть найдены в текущем каталоге. Если вы не хотите использовать $ LOAD_PATH, вы можете использовать require_relative для включения файлов из относительного каталога.

ВАЖНО – Здесь оба файла содержат одно и то же имя функции. Таким образом, это приведет к неоднозначности кода при включении в вызывающую программу, но модули избегают этой неоднозначности кода, и мы можем вызывать соответствующую функцию, используя имя модуля.

Ruby включает заявление

Вы можете встроить модуль в класс. Чтобы встроить модуль в класс, вы используете оператор включения в классе –

Синтаксис

include modulename

Если модуль определен в отдельном файле, то перед включением модуля в класс необходимо включить этот файл с помощью оператора require .

пример

Рассмотрим следующий модуль, написанный в файле support.rb .

module Week
   FIRST_DAY = "Sunday"
   def Week.weeks_in_month
      puts "You have four weeks in a month"
   end
   def Week.weeks_in_year
      puts "You have 52 weeks in a year"
   end
end

Теперь вы можете включить этот модуль в класс следующим образом:

#!/usr/bin/ruby
$LOAD_PATH << '.'
require "support"

class Decade
include Week
   no_of_yrs = 10
   def no_of_months
      puts Week::FIRST_DAY
      number = 10*12
      puts number
   end
end
d1 = Decade.new
puts Week::FIRST_DAY
Week.weeks_in_month
Week.weeks_in_year
d1.no_of_months

Это даст следующий результат –

Sunday
You have four weeks in a month
You have 52 weeks in a year
Sunday
120

Mixins в рубине

Прежде чем перейти к этому разделу, мы предполагаем, что вы знакомы с объектно-ориентированными концепциями.

Когда класс может наследовать функции от более чем одного родительского класса, класс должен показывать множественное наследование.

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

Миксины дают вам удивительно контролируемый способ добавления функциональности в классы. Однако их истинная сила проявляется, когда код в миксине начинает взаимодействовать с кодом в классе, который его использует.

Давайте рассмотрим следующий пример кода, чтобы понять миксин –

module A
   def a1
   end
   def a2
   end
end
module B
   def b1
   end
   def b2
   end
end

class Sample
include A
include B
   def s1
   end
end

samp = Sample.new
samp.a1
samp.a2
samp.b1
samp.b2
samp.s1

Модуль A состоит из методов a1 и a2. Модуль B состоит из методов b1 и b2. Класс Sample включает в себя оба модуля A и B. Класс Sample может обращаться ко всем четырем методам, а именно, a1, a2, b1 и b2. Таким образом, вы можете видеть, что класс Sample наследуется от обоих модулей. Таким образом, можно сказать, что класс Sample показывает множественное наследование или миксин .

Рубин – Струны

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

Простейшие строковые литералы заключены в одинарные кавычки (символ апострофа). Текст в кавычках является значением строки –

'This is a simple Ruby string literal'

Если вам нужно поместить апостроф внутри строкового литерала в одинарных кавычках, поставьте перед ним обратную косую черту, чтобы интерпретатор Ruby не думал, что он заканчивает строку –

'Won\'t you read O\'Reilly\'s book?'

Обратная косая черта также работает, чтобы избежать другой обратной косой черты, так что вторая обратная косая черта сама по себе не интерпретируется как escape-символ.

Ниже приведены особенности Ruby, связанные со строками.

Замена выражения

Подстановка выражений – это способ встраивания значения любого выражения Ruby в строку, используя # {и} –

Live Demo

#!/usr/bin/ruby

x, y, z = 12, 36, 72
puts "The value of x is #{ x }."
puts "The sum of x and y is #{ x + y }."
puts "The average was #{ (x + y + z)/3 }."

Это даст следующий результат –

The value of x is 12.
The sum of x and y is 48.
The average was 40.

Строки с разделителями

С помощью общих строк с разделителями вы можете создавать строки внутри пары совпадающих, хотя произвольных символов-разделителей, например!, (, {, <И т. Д., Перед которыми стоит символ процента (%). Q, q и x имеют специальные значения Общие строки с разделителями могут быть –

%{Ruby is fun.}  equivalent to "Ruby is fun."
%Q{ Ruby is fun. } equivalent to " Ruby is fun. "
%q[Ruby is fun.]  equivalent to a single-quoted string
%x!ls! equivalent to back tick command output `ls`

Побег персонажей

ПРИМЕЧАНИЕ. – В строке в двойных кавычках экранирующий символ интерпретируется; в строке в одинарных кавычках сохраняется экранирующий символ.

Кодировка символов

Набор символов по умолчанию для Ruby – ASCII, символы которого могут быть представлены одиночными байтами. Если вы используете UTF-8 или другой современный набор символов, символы могут быть представлены от одного до четырех байтов.

Вы можете изменить свой набор символов, используя $ KCODE в начале вашей программы, например так:

$KCODE = 'u'

ASCII (такой же, как ни один). Это по умолчанию.

е

EUC.

N

Нет (так же, как ASCII).

U

UTF-8.

Строковые встроенные методы

Нам нужен экземпляр объекта String для вызова метода String. Ниже приведен способ создания экземпляра объекта String –

new [String.new(str = "")]

Это вернет новый строковый объект, содержащий копию str . Теперь, используя объект str , мы все можем использовать любые доступные методы экземпляра. Например –

Live Demo

#!/usr/bin/ruby

myStr = String.new("THIS IS TEST")
foo = myStr.downcase

puts "#{foo}"

Это даст следующий результат –

this is test

str% arg

Форматирует строку, используя спецификацию формата. Аргумент должен быть массивом, если он содержит более одной подстановки. Для получения информации о спецификации формата см. Sprintf в разделе «Модуль ядра».

str * integer

Возвращает новую строку, содержащую целое число раз str. Другими словами, str повторяется целое число.

str + other_str

Объединяет other_str на ул.

ул << объект

Объединяет объект на ул. Если объект является Fixnum в диапазоне 0,255, он преобразуется в символ. Сравните это с concat.

str <=> other_str

Сравнивает str с other_str, возвращая -1 (меньше), 0 (равно) или 1 (больше). Сравнение чувствительно к регистру.

str == obj

Проверяет str и obj на равенство. Если obj не является строкой, возвращает false; возвращает true, если str <=> obj возвращает 0.

str = ~ obj

Сопоставляет str с шаблоном регулярного выражения obj. Возвращает позицию, где начинается матч; иначе ложно.

str.capitalize

Заглавная строка.

str.capitalize!

То же, что и с заглавной буквы, но изменения сделаны на месте.

str.casecmp

Делает сравнение строк без учета регистра.

str.center

Центрирует строку.

str.chomp

Удаляет разделитель записей ($ /), обычно \ n, с конца строки. Если разделитель записей не существует, ничего не делает.

str.chomp!

То же, что chomp, но изменения сделаны на месте.

str.chop

Удаляет последний символ в ул.

str.chop!

То же, что и chop, но изменения сделаны на месте.

str.concat (other_str)

Объединяет other_str на ул.

str.count (str, …)

Считает один или несколько наборов символов. Если существует более одного набора символов, считается пересечение этих наборов

str.crypt (other_str)

Применяет односторонний криптографический хеш к str. Аргументом является строка соли, которая должна быть длиной два символа, каждый символ находится в диапазоне az, AZ, 0.9,. или же /.

str.delete (other_str, …)

Возвращает копию строки со всеми символами в пересечении удаленных аргументов.

str.delete! (other_str, …)

То же самое, что и удаление, но изменения сделаны на месте.

str.downcase

Возвращает копию строки со всеми заглавными буквами, замененными строчными.

str.downcase!

То же, что и в нижнем регистре, но изменения сделаны на месте.

str.dump

Возвращает версию str, в которой все непечатаемые символы заменены на \ nnn, а все специальные символы экранированы.

str.each (separator = $ /) {| substr | блок}

Разделяет str, используя аргумент в качестве разделителя записей ($ / по умолчанию), передавая каждую подстроку в предоставленный блок.

str.each_byte {| fixnum | блок}

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

str.each_line (разделитель = $ /) {| substr | блок}

Разделяет str, используя аргумент в качестве разделителя записей ($ / по умолчанию), передавая каждую подстроку в предоставленный блок.

str.empty?

Возвращает true, если str пуст (имеет нулевую длину).

str.eql? (другое)

Две строки равны, если они имеют одинаковую длину и содержание.

str.gsub (шаблон, замена) [или]

str.gsub (pattern) {| match | блок}

Возвращает копию str со всеми вхождениями шаблона, замененными либо заменой, либо значением блока. Шаблон обычно будет регулярным выражением; если это String, то метасимволы регулярного выражения не будут интерпретироваться (то есть / \ d / будет соответствовать цифре, но \ d будет соответствовать обратной косой черте, за которой следует ‘d’).

str [fixnum] [или] str [fixnum, fixnum] [или] str [диапазон] [или] str [регулярное выражение] [или] str [регулярное выражение, fixnum] [или] str [other_str]

Ссылки str, используя следующие аргументы: один Fixnum, возвращает код символа в fixnum; два Fixnum, возвращает подстроку, начиная со смещения (первый fixnum) до длины (второй fixnum); диапазон, возвращает подстроку в диапазоне; регулярное выражение возвращает часть совпавшей строки; регулярное выражение с fixnum, возвращает сопоставленные данные в fixnum; other_str возвращает подстроку, соответствующую other_str. Отрицательный Fixnum начинается в конце строки с -1.

str [fixnum] = fixnum [или] str [fixnum] = new_str [или] str [fixnum, fixnum] = new_str [или] str [range] = aString [или] str [regexp] = новый_str [или] str [регулярное выражение , fixnum] = new_str [or] str [other_str] = new_str]

Заменить (назначить) всю или часть строки. Синоним среза!

str.gsub! (шаблон, замена) [или] str.gsub! (шаблон) {| match | block}

Выполняет подстановки String # gsub на месте, возвращая str или nil, если подстановки не выполнялись.

str.hash

Возвращает хеш на основе длины строки и содержимого.

str.hex

Обрабатывает начальные символы из str как строку шестнадцатеричных цифр (с необязательным знаком и необязательным 0x) и возвращает соответствующее число. Ноль возвращается при ошибке.

str.include? other_str [или] str.include? Fixnum

Возвращает true, если str содержит данную строку или символ.

str.index (подстрока [, смещение]) [или]

str.index (fixnum [, offset]) [or]

str.index (регулярное выражение [, смещение])

Возвращает индекс первого вхождения данной подстроки, символа (fixnum) или шаблона (regexp) в строке str. Возвращает ноль, если не найден. Если присутствует второй параметр, он указывает позицию в строке, с которой начинается поиск.

str.insert (index, other_str)

Вставляет other_str перед символом по указанному индексу, изменяя str. Отрицательные индексы отсчитываются от конца строки и вставляются после заданного символа. Намерение состоит в том, чтобы вставить строку так, чтобы она начиналась с заданного индекса.

str.inspect

Возвращает версию для печати str с экранированными специальными символами.

str.intern [or] str.to_sym

Возвращает Символ, соответствующий str, создавая символ, если он не существовал ранее.

str.length

Возвращает длину ул. Сравните размер.

str.ljust (integer, padstr = ”)

Если целое число больше, чем длина строки, возвращает новую строку с целым числом длины с выравниванием по левому краю и дополнением padstr; в противном случае возвращает ул.

str.lstrip

Возвращает копию str с удаленными начальными пробелами.

str.lstrip!

Удаляет начальные пробелы из str, возвращая nil, если не было внесено никаких изменений.

str.match (шаблон)

Преобразует шаблон в регулярное выражение (если он еще не был), а затем вызывает его метод сопоставления на str.

str.oct

Обрабатывает первые символы строки как строку восьмеричных цифр (с необязательным знаком) и возвращает соответствующее число. Возвращает 0, если преобразование не удалось.

str.replace (other_str)

Заменяет содержимое и зараженность str соответствующими значениями в other_str.

str.reverse

Возвращает новую строку с символами из str в обратном порядке.

str.reverse!

Реверс на ул.

str.rindex (подстрока [, fixnum]) [или]

str.rindex (fixnum [, fixnum]) [или]

str.rindex (regexp [, fixnum])

Возвращает индекс последнего вхождения данной подстроки, символа (fixnum) или шаблона (regexp) в str. Возвращает ноль, если не найден. Если присутствует второй параметр, он указывает позицию в строке для завершения поиска. Символы, выходящие за пределы этой точки, рассматриваться не будут.

str.rjust (integer, padstr = ”)

Если целое число больше, чем длина строки, возвращает новую строку с целым числом длины с выравниванием по правому краю строки с дополнением padstr; в противном случае возвращает ул.

str.rstrip

Возвращает копию str с удаленными конечными пробелами.

str.rstrip!

Удаляет завершающие пробелы из str, возвращая ноль, если не было внесено никаких изменений.

str.scan (шаблон) [или]

str.scan (pattern) {| match, … | блок}

Обе формы перебирают str, совпадая с шаблоном (который может быть регулярным выражением или строкой). Для каждого совпадения результат генерируется и либо добавляется в массив результатов, либо передается в блок. Если шаблон не содержит групп, каждый отдельный результат состоит из совпавшей строки, $ &. Если шаблон содержит группы, каждый отдельный результат сам является массивом, содержащим одну запись на группу.

str.slice (fixnum) [или] str.slice (fixnum, fixnum) [или]

str.slice (диапазон) [или] str.slice (регулярное выражение) [или]

str.slice (регулярное выражение, fixnum) [или] str.slice (other_str)

Смотрите str [fixnum] и т. Д.

str.slice! (fixnum) [или] str.slice! (fixnum, fixnum) [или]

str.slice! (диапазон) [или] str.slice! (регулярное выражение) [или]

str.slice! (other_str)

Удаляет указанную часть из str и возвращает удаленную часть. Формы, которые принимают Fixnum, вызовут IndexError, если значение выходит за пределы диапазона; форма Range вызовет RangeError, а формы Regexp и String будут молча игнорировать назначение.

str.split (pattern = $, [limit])

Делит str на подстроки на основе разделителя, возвращая массив этих подстрок.

Если pattern является String, то его содержимое используется в качестве разделителя при разбиении str. Если шаблон представляет собой один пробел, str разделяется на пробельные символы, причем начальные пробельные символы и серии непрерывных пробельных символов игнорируются.

Если pattern является регулярным выражением, str делится там, где образец совпадает. Всякий раз, когда шаблон соответствует строке нулевой длины, строка разбивается на отдельные символы.

Если шаблон опущен, значение $; используется. Если $; равен nil (это значение по умолчанию), str разделяется на пробелы, как если бы “ были указаны.

Если параметр limit пропущен, завершающие нулевые поля подавляются. Если limit – положительное число, будет возвращено не более того количества полей (если limit – 1, вся строка возвращается как единственная запись в массиве). При отрицательном значении число возвращаемых полей не ограничено, а завершающие нулевые поля не подавляются.

str.squeeze ([other_str] *)

Создает набор символов из параметра (ов) other_str, используя процедуру, описанную для String # count. Возвращает новую строку, в которой серии одного и того же символа, встречающиеся в этом наборе, заменяются одним символом. Если аргументы не указаны, все серии идентичных символов заменяются одним символом.

str.squeeze! ([other_str] *)

Сжимает str на месте, возвращая либо str, либо ноль, если не было внесено никаких изменений.

str.strip

Возвращает копию str с удаленными начальными и конечными пробелами.

str.strip!

Удаляет начальные и конечные пробелы с ул. Возвращает ноль, если str не был изменен.

str.sub (шаблон, замена) [или]

str.sub (pattern) {| match | блок}

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

str.sub! (шаблон, замена) [или]

str.sub! (pattern) {| match | блок}

Выполняет подстановки String # sub на месте, возвращая str или nil, если подстановки не выполнялись.

str.succ [или] str.next

Возвращает преемника на ул.

str.succ! [или] str.next!

Эквивалент String # succ, но изменяет получателя на месте.

сумма (n = 16)

Возвращает базовую n-битную контрольную сумму символов в str, где n – необязательный параметр Fixnum, значение по умолчанию равно 16. Результатом является просто сумма двоичного значения каждого символа в str по модулю 2n – 1. Это не особенно хорошая контрольная сумма.

str.swapcase

Возвращает копию строки с заглавными буквенными символами, преобразованными в строчные и строчными.

str.swapcase!

Эквивалентно String # swapcase, но изменяет получателя на месте, возвращая str или nil, если не было внесено никаких изменений.

str.to_f

> Возвращает результат интерпретации начальных символов в str как числа с плавающей запятой. Посторонние символы после конца действительного числа игнорируются. Если в начале строки str нет действительного числа, возвращается 0.0. Этот метод никогда не вызывает исключение.

str.to_i (база = 10)

Возвращает результат интерпретации начальных символов в str как целочисленное основание (основание 2, 8, 10 или 16). Посторонние символы после конца действительного числа игнорируются. Если в начале строки str нет действительного числа, возвращается 0. Этот метод никогда не вызывает исключение.

str.to_s [или] str.to_str

Возвращает получатель.

str.tr (from_str, to_str)

Возвращает копию str с символами в from_str, замененными соответствующими символами в to_str. Если to_str короче, чем from_str, он дополняется последним символом. Обе строки могут использовать нотацию c1.c2 для обозначения диапазонов символов, а from_str может начинаться с ^, который обозначает все символы, кроме перечисленных.

str.tr! (from_str, to_str)

Переводит str на место, используя те же правила, что и String # tr. Возвращает str или nil, если не было внесено никаких изменений.

str.tr_s (from_str, to_str)

Обрабатывает копию str, как описано в разделе String # tr, затем удаляет повторяющиеся символы в регионах, на которые повлиял перевод.

str.tr_s! (from_str, to_str)

Выполняет обработку String # tr_s для str на месте, возвращает str или nil, если не было внесено никаких изменений.

str.unpack (формат)

> Декодирует str (который может содержать двоичные данные) в соответствии со строкой формата, возвращая массив каждого извлеченного значения. Строка формата состоит из последовательности односимвольных директив, обобщенных в Таблице 18. За каждой директивой может следовать число, указывающее количество повторений с этой директивой. Звездочка (*) будет использовать все оставшиеся элементы. Каждая из директив sSiIlL может сопровождаться подчеркиванием (_), чтобы использовать собственный размер базовой платформы для указанного типа; в противном случае он использует независимый от платформы постоянный размер. Пробелы игнорируются в строке формата.

str.upcase

Возвращает копию str, в которой все строчные буквы заменены на прописные. Операция не зависит от локали. Это касается только символов от a до z.

str.upcase!

Изменяет содержимое строки в верхний регистр, возвращая ноль, если не было сделано никаких изменений.

str.upto (other_str) {| s | блок}

Выполняет итерацию последовательных значений, начиная с str и заканчивая включением other_str, передавая каждое значение по очереди в блок. Метод String # succ используется для генерации каждого значения.

Директива по распаковке струн

пример

Попробуйте следующий пример, чтобы распаковать различные данные.

"abc \0\0abc \0\0".unpack('A6Z6')   #=> ["abc", "abc "]
"abc \0\0".unpack('a3a3')           #=> ["abc", " \000\000"]
"abc \0abc \0".unpack('Z*Z*')       #=> ["abc ", "abc "]
"aa".unpack('b8B8')                 #=> ["10000110", "01100001"]
"aaa".unpack('h2H2c')               #=> ["16", "61", 97]
"\xfe\xff\xfe\xff".unpack('sS')     #=> [-2, 65534]
"now = 20is".unpack('M*')           #=> ["now is"]
"whole".unpack('xax2aX2aX1aX2a')    #=> ["h", "e", "l", "l", "o"]

Рубин – Массивы

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

Индексирование массива начинается с 0, как в C или Java. Отрицательный индекс предполагается относительно конца массива, то есть индекс -1 указывает на последний элемент массива, -2 – следующий за последним элементом в массиве, и так далее.

Массивы Ruby могут содержать такие объекты, как String, Integer, Fixnum, Hash, Symbol и даже другие объекты Array. Массивы Ruby не так жестки, как массивы в других языках. Массивы Ruby растут автоматически при добавлении к ним элементов.

Создание массивов

Есть много способов создать или инициализировать массив. Один из способов – с помощью нового метода класса –

names = Array.new

Вы можете установить размер массива во время создания массива –

names = Array.new(20)

Имена массивов теперь имеют размер или длину 20 элементов. Вы можете вернуть размер массива с помощью методов size или length –

Live Demo

 #! / USR / бен / рубин

 names = Array.new (20)
 ставит names.size # Возвращает 20
 ставит names.length # Это также возвращает 20

Это даст следующий результат –

20
20

Вы можете присвоить значение каждому элементу в массиве следующим образом:

Live Demo

#!/usr/bin/ruby

names = Array.new(4, "mac")
puts "#{names}"

Это даст следующий результат –

["mac", "mac", "mac", "mac"]

Вы также можете использовать блок с новым, заполняя каждый элемент тем, что оценивает блок:

Live Demo

#!/usr/bin/ruby

nums = Array.new(10) { |e| e = e * 2 }
puts "#{nums}"

Это даст следующий результат –

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

Есть еще один метод Array, []. Это работает так –

nums = Array.[](1, 2, 3, 4,5)

Еще одна форма создания массива выглядит следующим образом –

nums = Array[1, 2, 3, 4,5]

Модуль ядра, доступный в ядре Ruby, имеет метод Array, который принимает только один аргумент. Здесь метод принимает диапазон в качестве аргумента для создания массива цифр –

Live Demo

#!/usr/bin/ruby

digits = Array(0..9)
puts "#{digits}"

Это даст следующий результат –

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Встроенные методы массива

Нам нужен экземпляр объекта Array для вызова метода Array. Как мы уже видели, следующий способ создания экземпляра объекта Array –

Array.[](...) [or] Array[...] [or] [...]

Это вернет новый массив, заполненный данными объектами. Теперь, используя созданный объект, мы можем вызвать любые доступные методы экземпляра. Например –

Live Demo

#!/usr/bin/ruby

digits = Array(0..9)
num = digits.at(6)
puts "#{num}"

Это даст следующий результат –

 6

массив & other_array

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

массив * int [или] массив * str

Возвращает новый массив, созданный путем объединения int-копий self. С аргументом String, эквивалентным self.join (str).

массив + other_array

Возвращает новый массив, созданный путем объединения двух массивов вместе для создания третьего массива.

массив – other_array

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

массив <=> other_array

Сравнивает str с other_str, возвращая -1 (меньше), 0 (равно) или 1 (больше). Сравнение чувствительно к регистру.

массив | other_array

Возвращает новый массив, объединяя массив с other_array, удаляя дубликаты.

массив << объект

Выдвигает данный объект в конец массива. Это выражение возвращает сам массив, поэтому несколько добавлений могут быть объединены в цепочку.

массив <=> other_array

Возвращает целое число (-1, 0 или +1), если этот массив меньше, равен или больше, чем other_array.

массив == other_array

Два массива равны, если они содержат одинаковое количество элементов и если каждый элемент равен (согласно Object. ==) соответствующему элементу в другом массиве.

массив [индекс] [или] массив [начало, длина] [или]

массив [диапазон] [или] массив.slice (индекс) [или]

array.slice (начало, длина) [или] array.slice (диапазон)

Возвращает элемент по индексу , или возвращает подмассив, начинающийся с начала и продолжающийся для элементов длины , или возвращает подмассив, указанный диапазоном . Отрицательные индексы отсчитываются в обратном направлении от конца массива (-1 – последний элемент). Возвращает ноль, если индекс (или начальный индекс) находится вне диапазона.

массив [индекс] = объект [или]

массив [начало, длина] = объект или an_array или ноль [или]

array [range] = obj или an_array или nil

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

array.abbrev (pattern = nil)

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

array.assoc (OBJ)

Выполняет поиск в массиве, элементы которого также являются массивами, сравнивая obj с первым элементом каждого содержащегося в нем массива, используя obj. ==. Возвращает первый содержащийся массив, который соответствует или равен нулю, если совпадение не найдено.

array.at (индекс)

Возвращает элемент по индексу. Отрицательный индекс отсчитывает с конца себя. Возвращает ноль, если индекс находится вне диапазона.

array.clear

Удаляет все элементы из массива.

array.collect {| item | блок} [или]

array.map {| item | блок}

Вызывает блок один раз для каждого элемента себя . Создает новый массив, содержащий значения, возвращаемые блоком.

array.collect! {| пункт | блок} [или]

array.map! {| пункт | блок}

Вызывает блок один раз для каждого элемента self , заменяя элемент значением, возвращаемым блоком .

array.compact

Возвращает копию себя со всеми удаленными элементами nil .

array.compact!

Удаляет ноль элементов из массива. Возвращает ноль, если не было внесено никаких изменений.

Array.concat (other_array)

Добавляет элементы в other_array к себе .

array.delete (obj) [или]

array.delete (obj) {блок}

Удаляет из себя элементы, равные obj . Если элемент не найден, возвращается ноль . Если задан необязательный блок кода, возвращает результат блока, если элемент не найден.

array.delete_at (индекс)

Удаляет элемент по указанному индексу , возвращая этот элемент, или nil, если индекс выходит за пределы диапазона.

array.delete_if {| item | блок}

Удаляет каждый элемент self, для которого блок оценивается как true.

array.each {| item | блок}

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

array.each_index {| index | блок}

То же, что Array # each, но передает сам индекс элемента вместо самого элемента.

array.empty?

Возвращает true, если массив self не содержит элементов.

array.eql? (другое)

Возвращает true, если массив и другие являются одним и тем же объектом или являются массивами с одинаковым содержимым.

array.fetch (index) [или]

array.fetch (индекс, по умолчанию) [или]

array.fetch (index) {| index | блок}

Пытается вернуть элемент по индексу позиции. Если index находится вне массива, первая форма выдает исключение IndexError , вторая форма возвращает значение по умолчанию , а третья форма возвращает значение вызывающего блока , передавая индекс . Отрицательные значения индекса отсчитываются от конца массива.

array.fill (obj) [или]

array.fill (obj, start [, length]) [or]

array.fill (obj, range) [или]

array.fill {| index | блок} [или]

array.fill (start [, length]) {| index | блок} [или]

array.fill (range) {| index | блок}

Первые три формы устанавливают выбранные элементы self в obj . Начало нуля эквивалентно нулю. Длина ноль эквивалентна self.length . Последние три формы заполняют массив значением блока. Блок передается с абсолютным индексом каждого элемента для заполнения.

array.first [или]

array.first (п)

Возвращает первый элемент или первые n элементов массива. Если массив пуст, первая форма возвращает ноль , а вторая форма возвращает пустой массив.

array.flatten

Возвращает новый массив, который является одномерным уплощением этого массива (рекурсивно).

array.flatten!

Выравнивает массив на месте. Возвращает ноль, если не было внесено никаких изменений. (массив не содержит подмассивов.)

array.frozen?

Возвращает true, если массив заморожен (или временно заморожен во время сортировки).

array.hash

Вычисляет хеш-код для массива. Два массива с одинаковым содержимым будут иметь одинаковый хеш-код.

array.include? (объект)

Возвращает true, если obj присутствует в self , иначе false.

array.index (OBJ)

Возвращает индекс первого объекта в себе, который ==, для obj. Возвращает ноль, если совпадений не найдено.

array.indexes (i1, i2, … iN) [или]

array.indices (i1, i2, … iN)

Этот метод устарел в последней версии Ruby, поэтому используйте Array # values_at.

array.indices (i1, i2, … iN) [или]

array.indexes (i1, i2, … iN)

Этот метод устарел в последней версии Ruby, поэтому используйте Array # values_at.

array.insert (index, obj …)

Вставляет заданные значения перед элементом с заданным индексом (который может быть отрицательным).

array.inspect

Создает версию для печати массива.

array.join (sep = $,)

Возвращает строку, созданную путем преобразования каждого элемента массива в строку, разделенную символом sep .

array.last [или] array.last (n)

Возвращает последний элемент (ы) себя . Если массив пуст , первая форма возвращает ноль .

array.length

Возвращает количество элементов в себе . Может быть ноль.

array.map {| item | блок} [или]

array.collect {| item | блок}

Вызывает блок один раз для каждого элемента себя . Создает новый массив, содержащий значения, возвращаемые блоком.

array.map! {| пункт | блок} [или]

array.collect! {| пункт | блок}

Вызывает блок один раз для каждого элемента массива , заменяя элемент значением, возвращаемым блоком.

array.nitems

Возвращает количество ненулевых элементов в self . Может быть ноль.

array.pack (aTemplateString)

Упакует содержимое массива в двоичную последовательность в соответствии с директивами TemplateString. За директивами A, a и Z может следовать счет, который дает ширину результирующего поля. Остальные директивы также могут иметь счетчик, указывающий количество элементов массива для преобразования. Если счетчик является звездочкой (*), все остальные элементы массива будут преобразованы. Любая из директив все еще может сопровождаться подчеркиванием (_), чтобы использовать собственный размер базовой платформы для указанного типа; в противном случае они используют платформенно-независимый размер. Пробелы игнорируются в строке шаблона.

array.pop

Удаляет последний элемент из массива и возвращает его, или nil, если массив пуст.

array.push (obj, …)

Выдвигает (добавляет) данный объект в конец этого массива. Это выражение возвращает сам массив, поэтому несколько добавлений могут быть объединены в цепочку.

array.rassoc (ключ)

Поиск по массиву, элементы которого также являются массивами. Сравнивает ключ со вторым элементом каждого содержащегося в нем массива, используя ==. Возвращает первый содержащийся массив, который соответствует.

array.reject {| item | блок}

Возвращает новый массив, содержащий массив элементов, для которого блок не соответствует действительности .

array.reject! {| пункт | блок}

Удаляет элементы из массива, для которого блок оценивается как true , но возвращает nil, если не было внесено никаких изменений. Эквивалентно Array # delete_if.

array.replace (other_array)

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

array.reverse

Возвращает новый массив, содержащий элементы массива в обратном порядке.

array.reverse!

Обращает массив на месте.

array.reverse_each {| item | блок}

То же, что и для массива #, но перемещает массив в обратном порядке.

array.rindex (OBJ)

Возвращает индекс последнего объекта в массиве == в obj. Возвращает ноль, если совпадений не найдено.

array.select {| item | блок}

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

Array.shift

Возвращает первый элемент self и удаляет его (сдвигая все остальные элементы вниз на один). Возвращает ноль, если массив пуст.

array.size

Возвращает длину массива (количество элементов). Псевдоним для длины.

array.slice (index) [или] array.slice (начало, длина) [или]

array.slice (range) [or] array [index] [или]

массив [начало, длина] [или] массив [диапазон]

Возвращает элемент по индексу , или возвращает подмассив, начинающийся с начала и продолжающийся для элементов длины , или возвращает подмассив, указанный диапазоном . Отрицательные индексы отсчитываются в обратном направлении от конца массива (-1 – последний элемент). Возвращает ноль, если индекс (или начальный индекс) находится вне диапазона.

array.slice! (index) [или] array.slice! (start, length) [или]

array.slice! (диапазон)

Удаляет элемент (ы), заданный индексом (необязательно с длиной) или диапазоном . Возвращает удаленный объект, подмассив или ноль, если индекс выходит за пределы диапазона.

array.sort [или] array.sort {| а, б | блок}

Возвращает новый массив, созданный сортировкой self.

Array.sort! [или] array.sort! {| а, б | блок}

Сортирует себя.

array.to_a

Возвращает себя . Если вызывается для подкласса Array , преобразует получателя в объект Array.

array.to_ary

Возвращает себя.

array.to_s

Возвращает self.join.

array.transpose

Предполагается, что self является массивом массивов и транспонирует строки и столбцы.

array.uniq

Возвращает новый массив, удаляя повторяющиеся значения в массиве .

array.uniq!

Удаляет дубликаты элементов от себя . Возвращает ноль, если не было внесено никаких изменений (то есть дубликаты не найдены).

array.unshift (obj, …)

Добавляет объекты в начало массива, остальные элементы – в один.

array.values_at (селектор, …)

Возвращает массив, содержащий элементы в self, соответствующие данному селектору (один или несколько). Селекторы могут быть целочисленными индексами или диапазонами.

array.zip (arg, …) [or]

array.zip (arg, …) {| обр | блок}

Преобразует любые аргументы в массивы, затем объединяет элементы массива с соответствующими элементами из каждого аргумента.

Директива по массиву

@

Перемещается в абсолютную позицию.

Строка ASCII (пробел дополняется, число равно ширине).

Строка ASCII (заполнено нулями, число равно ширине).

В

строка (нисходящий битовый порядок).

б

Битовая строка (возрастающий битовый порядок).

С

Неподписанный символ

с

Char.

D, D

Поплавок двойной точности, нативный формат.

Е

Поплавок двойной точности, порядок байтов в младшем порядке.

е

Поплавок одинарной точности, порядок байтов в младшем порядке.

F, F

Поплавок одинарной точности, нативный формат.

г

Поплавок двойной точности, сетевой (байтовый) порядок байтов.

г

Плавающая последовательность одинарной точности, сетевой (байтовый) порядок байтов.

ЧАС

Шестнадцатеричная строка (сначала высокий клев).

час

Шестнадцатеричная строка (сначала низкий клев)

я

Целое число без знака.

я

Integer.

L

Без подписи долго.

L

Долго.

M

Котируемая для печати, кодировка MIME (см. RFC 2045).

м

Строка в кодировке Base64.

N

Длинный сетевой порядок байтов.

N

Короткий, сетевой (big-endian) порядок байтов.

п

Указатель на структуру (строка фиксированной длины).

п

Указатель на строку с нулевым символом в конце.

Q, q

64-битное число.

S

Подпись короткая.

s

Короткий.

U

UTF-8.

U

UU-кодированная строка.

В

Длинный порядок байтов с прямым порядком байтов.

v

Короткий порядок байтов с прямым порядком байтов.

вес

BER-сжатое целое число \ fnm.

Икс

Резервное копирование байта.

Икс

Нулевой байт.

Z

То же, что a, за исключением того, что null добавляется с помощью *.

пример

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

Live Demo

a = [ "a", "b", "c" ]
n = [ 65, 66, 67 ]
puts a.pack("A3A3A3")   #=> "a  b  c  "
puts a.pack("a3a3a3")   #=> "a\000\000b\000\000c\000\000"
puts n.pack("ccc")      #=> "ABC"

Это даст следующий результат –

a  b  c
abc
ABC

Рубин – Хэши

Хеш – это набор пар ключ-значение, таких как: “employee” => “salary”. Он похож на массив, за исключением того, что индексирование выполняется с помощью произвольных ключей любого типа объекта, а не целочисленного индекса.

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

Создание хэшей

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

months = Hash.new

Вы также можете использовать new для создания хэша со значением по умолчанию, в противном случае просто nil

months = Hash.new( "month" )

or

months = Hash.new "month"

При доступе к любому ключу в хэше, который имеет значение по умолчанию, если ключ или значение не существует, доступ к хешу вернет значение по умолчанию –

Live Demo

#!/usr/bin/ruby

months = Hash.new( "month" )

puts "#{months[0]}"
puts "#{months[72]}"

Это даст следующий результат –

month
month

Live Demo

#!/usr/bin/ruby

H = Hash["a" => 100, "b" => 200]

puts "#{H['a']}"
puts "#{H['b']}"

Это даст следующий результат –

100
200

Вы можете использовать любой объект Ruby в качестве ключа или значения, даже массив, поэтому следующий пример является допустимым:

[1,"jan"] => "January"

Встроенные методы хэширования

Нам нужен экземпляр объекта Hash для вызова метода Hash. Как мы уже видели, следующий способ создания экземпляра объекта Hash –

Hash[[key =>|, value]* ] or

Hash.new [or] Hash.new(obj) [or]
Hash.new { |hash, key| block }

Это вернет новый хеш, заполненный данными объектами. Теперь, используя созданный объект, мы можем вызывать любые доступные методы экземпляра. Например –

Live Demo

#!/usr/bin/ruby

$, = ", "
months = Hash.new( "month" )
months = {"1" => "January", "2" => "February"}

keys = months.keys
puts "#{keys}"

Это даст следующий результат –

["1", "2"]

Ниже приведены публичные методы хеширования (при условии, что хеш является объектом массива):

Sr.No. Методы и описание
1

хэш == другой_хэш

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

2

хэш. [ключ]

Используя ключ, ссылается на значение из хэша. Если ключ не найден, возвращает значение по умолчанию.

3

хеш. [ключ] = значение

Связывает значение, заданное значением, с ключом, заданным ключом .

4

hash.clear

Удаляет все пары ключ-значение из хэша.

5

hash.default (ключ = ноль)

Возвращает значение по умолчанию для хэша , nil, если не установлено по умолчанию =. ([] возвращает значение по умолчанию, если ключ не существует в хэше .)

6

hash.default = obj

Устанавливает значение по умолчанию для хэша .

7

hash.default_proc

Возвращает блок, если хеш был создан блоком.

8

hash.delete (ключ) [или]

array.delete (key) {| ключ | блок}

Удаляет пару ключ-значение из хеша по ключу . Если используется блок, возвращает результат блока, если пара не найдена. Сравните delete_if .

9

hash.delete_if {| ключ, значение | блок}

Удаляет пару ключ-значение из хэша для каждой пары, для которой блок оценивается как true .

10

hash.each {| ключ, значение | блок}

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

11

hash.each_key {| ключ | блок}

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

12

hash.each_key {| key_value_array | блок}

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

13

hash.each_key {| value | блок}

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

14

hash.empty?

Проверяет, является ли хеш пустым (не содержит пар ключ-значение), возвращает true или false .

15

hash.fetch (ключ [, по умолчанию]) [или]

hash.fetch (ключ) {| ключ | блок}

Возвращает значение из хэша для данного ключа . Если ключ не может быть найден, и нет других аргументов, он вызывает исключение IndexError ; если задано значение по умолчанию , оно возвращается; если указан необязательный блок, возвращается его результат.

16

hash.has_key? (ключ) [или] hash.include? (ключ) [или]

hash.key? (ключ) [или] hash.member? (ключ)

Проверяет, присутствует ли данный ключ в хэше, возвращая true или false .

17

hash.has_value? (значение)

Проверяет, содержит ли хеш заданное значение .

18

hash.index (значение)

Возвращает ключ для заданного значения в хэше, nil, если не найдено подходящего значения.

19

hash.indexes (ключи)

Возвращает новый массив, состоящий из значений для данного ключа (ключей). Вставит значение по умолчанию для ключей, которые не найдены. Этот метод устарел. Используйте выбор.

20

hash.indices (ключи)

Возвращает новый массив, состоящий из значений для данного ключа (ключей). Вставит значение по умолчанию для ключей, которые не найдены. Этот метод устарел. Используйте выбор.

21

hash.inspect

Возвращает красивую строковую версию хэша.

22

hash.invert

Создает новый хеш , инвертируя ключи и значения из хеша ; то есть в новом хеше ключи из хэша становятся значениями, а значения становятся ключами.

23

hash.keys

Создает новый массив с ключами из хэша .

24

hash.length

Возвращает размер или длину хэша в виде целого числа.

25

hash.merge (other_hash) [или]

hash.merge (other_hash) {| ключ, oldval, newval | блок}

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

26

hash.merge! (other_hash) [или]

hash.merge! (other_hash) {| ключ, oldval, newval | блок}

То же, что слияние, но изменения выполняются на месте.

27

hash.rehash

Перестраивает хэш на основе текущих значений для каждого ключа . Если значения изменились с момента их вставки, этот метод переиндексирует хеш .

28

hash.reject {| ключ, значение | блок}

Создает новый хэш для каждой пары, блок оценивается как истинный

29

hash.reject! {| ключ, значение | блок}

То же самое, что отклонить , но изменения сделаны на месте.

30

hash.replace (other_hash)

Заменяет содержимое хеша на содержимое other_hash .

31

hash.select {| ключ, значение | блок}

Возвращает новый массив, состоящий из пар ключ-значение из хеша, для которого блок возвращает true .

32

hash.shift

Удаляет пару ключ-значение из хэша , возвращая ее в виде двухэлементного массива.

33

hash.size

Возвращает размер или длину хэша в виде целого числа.

34

hash.sort

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

35

hash.store (ключ, значение)

Сохраняет пару ключ-значение в хэше .

36

hash.to_a

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

37

hash.to_hash

Возвращает хеш (self).

38

hash.to_s

Преобразует хеш в массив, затем преобразует этот массив в строку.

39

hash.update (other_hash) [или]

hash.update (other_hash) {| ключ, oldval, newval | блок}

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

40

hash.value? (значение)

Проверяет, содержит ли хеш заданное значение .

41

hash.values

Возвращает новый массив, содержащий все значения хеша .

42

hash.values_at (obj, …)

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

хэш == другой_хэш

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

хэш. [ключ]

Используя ключ, ссылается на значение из хэша. Если ключ не найден, возвращает значение по умолчанию.

хеш. [ключ] = значение

Связывает значение, заданное значением, с ключом, заданным ключом .

hash.clear

Удаляет все пары ключ-значение из хэша.

hash.default (ключ = ноль)

Возвращает значение по умолчанию для хэша , nil, если не установлено по умолчанию =. ([] возвращает значение по умолчанию, если ключ не существует в хэше .)

hash.default = obj

Устанавливает значение по умолчанию для хэша .

hash.default_proc

Возвращает блок, если хеш был создан блоком.

hash.delete (ключ) [или]

array.delete (key) {| ключ | блок}

Удаляет пару ключ-значение из хеша по ключу . Если используется блок, возвращает результат блока, если пара не найдена. Сравните delete_if .

hash.delete_if {| ключ, значение | блок}

Удаляет пару ключ-значение из хэша для каждой пары, для которой блок оценивается как true .

hash.each {| ключ, значение | блок}

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

hash.each_key {| ключ | блок}

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

hash.each_key {| key_value_array | блок}

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

hash.each_key {| value | блок}

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

hash.empty?

Проверяет, является ли хеш пустым (не содержит пар ключ-значение), возвращает true или false .

hash.fetch (ключ [, по умолчанию]) [или]

hash.fetch (ключ) {| ключ | блок}

Возвращает значение из хэша для данного ключа . Если ключ не может быть найден, и нет других аргументов, он вызывает исключение IndexError ; если задано значение по умолчанию , оно возвращается; если указан необязательный блок, возвращается его результат.

hash.has_key? (ключ) [или] hash.include? (ключ) [или]

hash.key? (ключ) [или] hash.member? (ключ)

Проверяет, присутствует ли данный ключ в хэше, возвращая true или false .

hash.has_value? (значение)

Проверяет, содержит ли хеш заданное значение .

hash.index (значение)

Возвращает ключ для заданного значения в хэше, nil, если не найдено подходящего значения.

hash.indexes (ключи)

Возвращает новый массив, состоящий из значений для данного ключа (ключей). Вставит значение по умолчанию для ключей, которые не найдены. Этот метод устарел. Используйте выбор.

hash.indices (ключи)

Возвращает новый массив, состоящий из значений для данного ключа (ключей). Вставит значение по умолчанию для ключей, которые не найдены. Этот метод устарел. Используйте выбор.

hash.inspect

Возвращает красивую строковую версию хэша.

hash.invert

Создает новый хеш , инвертируя ключи и значения из хеша ; то есть в новом хеше ключи из хэша становятся значениями, а значения становятся ключами.

hash.keys

Создает новый массив с ключами из хэша .

hash.length

Возвращает размер или длину хэша в виде целого числа.

hash.merge (other_hash) [или]

hash.merge (other_hash) {| ключ, oldval, newval | блок}

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

hash.merge! (other_hash) [или]

hash.merge! (other_hash) {| ключ, oldval, newval | блок}

То же, что слияние, но изменения выполняются на месте.

hash.rehash

Перестраивает хэш на основе текущих значений для каждого ключа . Если значения изменились с момента их вставки, этот метод переиндексирует хеш .

hash.reject {| ключ, значение | блок}

Создает новый хэш для каждой пары, блок оценивается как истинный

hash.reject! {| ключ, значение | блок}

То же самое, что отклонить , но изменения сделаны на месте.

hash.replace (other_hash)

Заменяет содержимое хеша на содержимое other_hash .

hash.select {| ключ, значение | блок}

Возвращает новый массив, состоящий из пар ключ-значение из хеша, для которого блок возвращает true .

hash.shift

Удаляет пару ключ-значение из хэша , возвращая ее в виде двухэлементного массива.

hash.size

Возвращает размер или длину хэша в виде целого числа.

hash.sort

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

hash.store (ключ, значение)

Сохраняет пару ключ-значение в хэше .

hash.to_a

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

hash.to_hash

Возвращает хеш (self).

hash.to_s

Преобразует хеш в массив, затем преобразует этот массив в строку.

hash.update (other_hash) [или]

hash.update (other_hash) {| ключ, oldval, newval | блок}

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

hash.value? (значение)

Проверяет, содержит ли хеш заданное значение .

hash.values

Возвращает новый массив, содержащий все значения хеша .

hash.values_at (obj, …)

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

Рубин – Дата и время

Класс Time представляет даты и время в Ruby. Это тонкий слой над системной датой и временем, предоставляемыми операционной системой. Этот класс может быть не в вашей системе для представления дат до 1970 или после 2038 года.

Эта глава знакомит вас со всеми наиболее востребованными понятиями даты и времени.

Получение текущей даты и времени

Ниже приведен простой пример получения текущей даты и времени.

Live Demo

#!/usr/bin/ruby -w

time1 = Time.new
puts "Current Time : " + time1.inspect

# Time.now is a synonym:
time2 = Time.now
puts "Current Time : " + time2.inspect

Это даст следующий результат –

Current Time : Mon Jun 02 12:02:39 -0700 2008
Current Time : Mon Jun 02 12:02:39 -0700 2008

Получение компонентов даты и времени

Мы можем использовать объект Time для получения различных компонентов даты и времени. Ниже приведен пример, показывающий то же самое –

Live Demo

#!/usr/bin/ruby -w

time = Time.new

# Components of a Time
puts "Current Time : " + time.inspect
puts time.year    # => Year of the date 
puts time.month   # => Month of the date (1 to 12)
puts time.day     # => Day of the date (1 to 31 )
puts time.wday    # => 0: Day of week: 0 is Sunday
puts time.yday    # => 365: Day of year
puts time.hour    # => 23: 24-hour clock
puts time.min     # => 59
puts time.sec     # => 59
puts time.usec    # => 999999: microseconds
puts time.zone    # => "UTC": timezone name

Это даст следующий результат –

Current Time : Mon Jun 02 12:03:08 -0700 2008
2008
6
2
1
154
12
3
8
247476
UTC

Функции Time.utc, Time.gm и Time.local

Эти две функции можно использовать для форматирования даты в стандартном формате следующим образом:

# July 8, 2008
Time.local(2008, 7, 8)  
# July 8, 2008, 09:10am, local time
Time.local(2008, 7, 8, 9, 10)   
# July 8, 2008, 09:10 UTC
Time.utc(2008, 7, 8, 9, 10)  
# July 8, 2008, 09:10:11 GMT (same as UTC)
Time.gm(2008, 7, 8, 9, 10, 11)  

Ниже приведен пример получения всех компонентов в массиве в следующем формате:

[sec,min,hour,day,month,year,wday,yday,isdst,zone]

Попробуйте следующее –

Live Demo

#!/usr/bin/ruby -w

time = Time.new
values = time.to_a
p values

Это сгенерирует следующий результат –

[26, 10, 12, 2, 6, 2008, 1, 154, false, "MST"]

Этот массив можно передать в функции Time.utc или Time.local, чтобы получить другой формат дат следующим образом:

Live Demo

#!/usr/bin/ruby -w

time = Time.new
values = time.to_a
puts Time.utc(*values)

Это сгенерирует следующий результат –

Mon Jun 02 12:15:36 UTC 2008

Ниже приведен способ получения времени, представленного внутренне в секундах с (зависимой от платформы) эпохи –

# Returns number of seconds since epoch
time = Time.now.to_i  

# Convert number of seconds into Time object.
Time.at(time)

# Returns second since epoch which includes microseconds
time = Time.now.to_f

Часовые пояса и летнее время

Вы можете использовать объект Time для получения всей информации, связанной с часовыми поясами и переходом на летнее время, следующим образом:

time = Time.new

# Here is the interpretation
time.zone       # => "UTC": return the timezone
time.utc_offset # => 0: UTC is 0 seconds offset from UTC
time.zone       # => "PST" (or whatever your timezone is)
time.isdst      # => false: If UTC does not have DST.
time.utc?       # => true: if t is in UTC time zone
time.localtime  # Convert to local timezone.
time.gmtime     # Convert back to UTC.
time.getlocal   # Return a new Time object in local zone
time.getutc     # Return a new Time object in UTC

Форматирование времени и даты

Существуют различные способы форматирования даты и времени. Вот один пример, показывающий несколько –

Live Demo

#!/usr/bin/ruby -w

time = Time.new
puts time.to_s
puts time.ctime
puts time.localtime
puts time.strftime("%Y-%m-%d %H:%M:%S")

Это даст следующий результат –

Mon Jun 02 12:35:19 -0700 2008
Mon Jun  2 12:35:19 2008
Mon Jun 02 12:35:19 -0700 2008
2008-06-02 12:35:19

Директивы форматирования времени

Эти директивы в следующей таблице используются с методом Time.strftime .

Sr.No. Директива и описание
1

% в

Сокращенное название дня недели (Солнце).

2

% A

Полное название дня недели (воскресенье).

3

% б

Сокращенное название месяца (январь).

4

% В

Полное название месяца (январь).

5

% с

Предпочтительное местное представление даты и времени.

6

% d

День месяца (с 01 по 31).

7

%ЧАС

Час дня, круглосуточные часы (с 00 до 23).

8

Час дня, 12-часовые часы (с 01 до 12).

9

% J

День года (от 001 до 366).

10

% м

Месяц года (от 01 до 12).

11

% M

Минута часа (от 00 до 59).

12

%п

Индикатор меридиана (AM или PM).

13

% S

Секунды минуты (от 00 до 60).

14

% U

Номер недели текущего года, начиная с первого воскресенья как первого дня первой недели (от 00 до 53).

15

% W

Номер недели текущего года, начиная с первого понедельника в качестве первого дня первой недели (от 00 до 53).

16

% мас

День недели (воскресенье 0, 0 до 6).

17

%Икс

Предпочитаемое представление только для даты, без времени.

18

%ИКС

Предпочитаемое представление только для времени, без даты.

19

% г

Год без века (от 00 до 99).

20

% Y

Год с веком.

21

% Z

Название часового пояса.

22

%%

Буквальный символ%.

% в

Сокращенное название дня недели (Солнце).

% A

Полное название дня недели (воскресенье).

% б

Сокращенное название месяца (январь).

% В

Полное название месяца (январь).

% с

Предпочтительное местное представление даты и времени.

% d

День месяца (с 01 по 31).

%ЧАС

Час дня, круглосуточные часы (с 00 до 23).

Час дня, 12-часовые часы (с 01 до 12).

% J

День года (от 001 до 366).

% м

Месяц года (от 01 до 12).

% M

Минута часа (от 00 до 59).

%п

Индикатор меридиана (AM или PM).

% S

Секунды минуты (от 00 до 60).

% U

Номер недели текущего года, начиная с первого воскресенья как первого дня первой недели (от 00 до 53).

% W

Номер недели текущего года, начиная с первого понедельника в качестве первого дня первой недели (от 00 до 53).

% мас

День недели (воскресенье 0, 0 до 6).

%Икс

Предпочитаемое представление только для даты, без времени.

%ИКС

Предпочитаемое представление только для времени, без даты.

% г

Год без века (от 00 до 99).

% Y

Год с веком.

% Z

Название часового пояса.

%%

Буквальный символ%.

Арифметика времени

Вы можете выполнить простую арифметику со временем следующим образом:

Live Demo

now = Time.now          # Current time
puts now

past = now - 10         # 10 seconds ago. Time - number => Time
puts past

future = now + 10  # 10 seconds from now Time + number => Time
puts future

diff = future - past     # => 10  Time - Time => number of seconds
puts diff

Это даст следующий результат –

Thu Aug 01 20:57:05 -0700 2013
Thu Aug 01 20:56:55 -0700 2013
Thu Aug 01 20:57:15 -0700 2013
20.0

Рубин – Диапазоны

Диапазоны встречаются везде: с января по декабрь, от 0 до 9, строки с 50 по 67 и т. Д. Ruby поддерживает диапазоны и позволяет использовать диапазоны различными способами –

  • Диапазоны как последовательности
  • Диапазоны как условия
  • Диапазоны как интервалы

Диапазоны как последовательности

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

Ruby создает эти последовательности, используя операторы диапазонов ” .. ” и ” … ” . Форма с двумя точками создает включающий диапазон, а форма с тремя точками создает диапазон, который исключает указанное высокое значение.

(1..5)        #==> 1, 2, 3, 4, 5
(1...5)       #==> 1, 2, 3, 4
('a'..'d')    #==> 'a', 'b', 'c', 'd'

Последовательность 1..100 хранится как объект Range, содержащий ссылки на два объекта Fixnum . Если вам нужно, вы можете преобразовать диапазон в список, используя метод to_a . Попробуйте следующий пример –

Live Demo

#!/usr/bin/ruby

$, =", "   # Array value separator
range1 = (1..10).to_a
range2 = ('bar'..'bat').to_a

puts "#{range1}"
puts "#{range2}"

Это даст следующий результат –

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
["bar", "bas", "bat"]

Диапазоны реализуют методы, которые позволяют вам перебирать их и тестировать их содержимое различными способами –

Live Demo

#!/usr/bin/ruby

# Assume a range
digits = 0..9

puts digits.include?(5)
ret = digits.min
puts "Min value is #{ret}"

ret = digits.max
puts "Max value is #{ret}"

ret = digits.reject {|i| i < 5 }
puts "Rejected values are #{ret}"

digits.each do |digit|
   puts "In Loop #{digit}"
end

Это даст следующий результат –

true
Min value is 0
Max value is 9
Rejected values are 5, 6, 7, 8, 9
In Loop 0
In Loop 1
In Loop 2
In Loop 3
In Loop 4
In Loop 5
In Loop 6
In Loop 7
In Loop 8
In Loop 9

Диапазоны как условия

Диапазоны также могут использоваться как условные выражения. Например, следующий фрагмент кода печатает наборы строк из стандартного ввода, где первая строка в каждом наборе содержит слово начало, а последняя строка заканчивается словом –

while gets
   print if /start/../end/
end

Диапазоны можно использовать в операторах case –

Live Demo

#!/usr/bin/ruby

score = 70

result = case score
   when 0..40 then "Fail"
   when 41..60 then "Pass"
   when 61..70 then "Pass with Merit"
   when 71..100 then "Pass with Distinction"
   else "Invalid Score"
end

puts result

Это даст следующий результат –

Pass with Merit

Диапазоны как интервалы

Окончательное использование универсального диапазона – это проверка интервала: определение того, попадает ли какое-либо значение в интервал, представленный диапазоном. Это делается с помощью ===, оператора равенства регистра.

Live Demo

#!/usr/bin/ruby

if ((1..10) === 5)
   puts "5 lies in (1..10)"
end

if (('a'..'j') === 'c')
   puts "c lies in ('a'..'j')"
end

if (('a'..'j') === 'z')
   puts "z lies in ('a'..'j')"
end

Это даст следующий результат –

5 lies in (1..10)
c lies in ('a'..'j')

Ruby – Итераторы

Итераторы – это не что иное, как методы, поддерживаемые коллекциями . Объекты, которые хранят группу элементов данных, называются коллекциями. В Ruby массивы и хэши можно назвать коллекциями.

Итераторы возвращают все элементы коллекции, один за другим. Мы будем обсуждать два итератора здесь, каждый и собирать . Давайте посмотрим на это подробно.

Руби каждый итератор

Каждый итератор возвращает все элементы массива или хеша.

Синтаксис

collection.each do |variable|
   code
end

Выполняет код для каждого элемента в коллекции . Здесь коллекция может быть массивом или хэшем ruby.

пример

Live Demo

#!/usr/bin/ruby

ary = [1,2,3,4,5]
ary.each do |i|
   puts i
end

Это даст следующий результат –

1
2
3
4
5

Вы всегда связываете каждый итератор с блоком. Он возвращает каждое значение массива, одно за другим, в блок. Значение сохраняется в переменной i и затем отображается на экране.

Ruby собирать итератор

Итератор сбора возвращает все элементы коллекции.

Синтаксис

collection = collection.collect

Метод сбора не всегда должен быть связан с блоком. Метод collect возвращает всю коллекцию независимо от того, является ли она массивом или хэшем.

пример

#!/usr/bin/ruby

a = [1,2,3,4,5]
b = Array.new
b = a.collect
puts b

Это даст следующий результат –

1
2
3
4
5

ПРИМЕЧАНИЕ. – Метод сбора данных не является правильным способом копирования между массивами. Существует еще один метод, называемый клоном , который следует использовать для копирования одного массива в другой.

Обычно вы используете метод collect, когда хотите что-то сделать с каждым из значений, чтобы получить новый массив. Например, этот код создает массив b, содержащий 10 раз каждое значение в a .

Live Demo

#!/usr/bin/ruby

a = [1,2,3,4,5]
b = a.collect{|x| 10*x}
puts b

Это даст следующий результат –

10
20
30
40
50

Ruby – File I / O

Ruby предоставляет полный набор методов ввода-вывода, реализованных в модуле Kernel. Все методы ввода / вывода являются производными от класса IO.

Класс IO предоставляет все основные методы, такие как чтение, запись, получение, ввод, readline, getc и printf .

В этой главе будут рассмотрены все основные функции ввода / вывода, доступные в Ruby. Для получения дополнительной информации, пожалуйста, обратитесь к Ruby Class IO .

Заявление пут

В предыдущих главах вы присвоили значения переменным, а затем распечатали выходные данные с помощью оператора put .

Оператор put указывает программе отображать значение, хранящееся в переменной. Это добавит новую строку в конце каждой строки, которую она пишет.

пример

Live Demo

#!/usr/bin/ruby

val1 = "This is variable one"
val2 = "This is variable two"
puts val1
puts val2

Это даст следующий результат –

This is variable one
This is variable two

Заявление получает

Оператор gets может использоваться для получения любого ввода от пользователя со стандартного экрана, называемого STDIN.

пример

Следующий код показывает, как использовать инструкцию gets. Этот код предложит пользователю ввести значение, которое будет сохранено в переменной val и, наконец, будет напечатано в STDOUT.

#!/usr/bin/ruby

puts "Enter a value :"
val = gets
puts val

Это даст следующий результат –

Enter a value :
This is entered value
This is entered value

Заявление Putc

В отличие от оператора put , который выводит всю строку на экран, оператор putc может использоваться для вывода по одному символу за раз.

пример

Вывод следующего кода – это просто символ H –

Live Demo

#!/usr/bin/ruby

str = "Hello Ruby!"
putc str

Это даст следующий результат –

H

Заявление о печати

Оператор print аналогичен оператору put . Единственное отличие состоит в том, что оператор put переходит на следующую строку после печати содержимого, тогда как в операторе print курсор располагается на той же строке.

пример

Live Demo

#!/usr/bin/ruby

print "Hello World"
print "Good Morning"

Это даст следующий результат –

Hello WorldGood Morning

Открытие и закрытие файлов

До сих пор вы читали и писали на стандартный ввод и вывод. Теперь посмотрим, как играть с реальными файлами данных.

Метод File.new

Вы можете создать объект File, используя метод File.new для чтения, записи или того и другого, в соответствии со строкой режима. Наконец, вы можете использовать метод File.close, чтобы закрыть этот файл.

Синтаксис

aFile = File.new("filename", "mode")
   # ... process the file
aFile.close

Метод File.open

Вы можете использовать метод File.open, чтобы создать новый объект файла и назначить этот объект файла файлу. Однако есть одно различие между методами File.open и File.new . Разница в том, что метод File.open можно связать с блоком, тогда как вы не можете сделать то же самое с помощью метода File.new .

File.open("filename", "mode") do |aFile|
   # ... process the file
end

р

Режим только для чтения. Указатель файла находится в начале файла. Это режим “по умолчанию”.

г +

Режим чтения-записи. Указатель файла будет в начале файла.

вес

Режим только для записи. Перезаписывает файл, если файл существует. Если файл не существует, создает новый файл для записи.

ш +

Режим чтения-записи. Перезаписывает существующий файл, если файл существует. Если файл не существует, создает новый файл для чтения и записи.

Режим только для записи. Указатель файла находится в конце файла, если файл существует. То есть файл находится в режиме добавления. Если файл не существует, он создает новый файл для записи.

а +

Режим чтения и записи. Указатель файла находится в конце файла, если файл существует. Файл открывается в режиме добавления. Если файл не существует, он создает новый файл для чтения и записи.

Чтение и запись файлов

Те же методы, которые мы использовали для «простого» ввода-вывода, доступны для всех файловых объектов. Итак, gets читает строку из стандартного ввода, а aFile.gets читает строку из объекта файла aFile.

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

Метод sysread

Вы можете использовать метод sysread, чтобы прочитать содержимое файла. Вы можете открыть файл в любом из режимов при использовании метода sysread. Например –

Ниже приведен текстовый файл ввода –

This is a simple text file for testing purpose.

Теперь давайте попробуем прочитать этот файл –

#!/usr/bin/ruby

aFile = File.new("input.txt", "r")
if aFile
   content = aFile.sysread(20)
   puts content
else
   puts "Unable to open file!"
end

Этот оператор выведет первые 20 символов файла. Указатель файла теперь будет размещен на 21-м символе в файле.

Метод syswrite

Вы можете использовать метод syswrite, чтобы записать содержимое в файл. Вам нужно открыть файл в режиме записи при использовании метода syswrite. Например –

#!/usr/bin/ruby

aFile = File.new("input.txt", "r+")
if aFile
   aFile.syswrite("ABCDEF")
else
   puts "Unable to open file!"
end

Это утверждение запишет «ABCDEF» в файл.

Метод each_byte

Этот метод относится к классу File . Метод each_byte всегда связан с блоком. Рассмотрим следующий пример кода –

#!/usr/bin/ruby

aFile = File.new("input.txt", "r+")
if aFile
   aFile.syswrite("ABCDEF")
   aFile.each_byte {|ch| putc ch; putc ?. }
else
   puts "Unable to open file!"
end

Символы передаются один за другим в переменную ch, а затем отображаются на экране следующим образом:

s. .a. .s.i.m.p.l.e. .t.e.x.t. .f.i.l.e. .f.o.r. .t.e.s.t.i.n.g. .p.u.r.p.o.s.e...
.
.

Метод IO.readlines

Класс File является подклассом класса IO. Класс IO также имеет несколько методов, которые можно использовать для манипулирования файлами.

Одним из методов класса IO является IO.readlines . Этот метод возвращает содержимое файла построчно. В следующем коде показано использование метода IO.readlines

#!/usr/bin/ruby

arr = IO.readlines("input.txt")
puts arr[0]
puts arr[1]

В этом коде переменная arr является массивом. Каждая строка файла input.txt будет элементом массива arr. Следовательно, arr [0] будет содержать первую строку, а arr [1] будет содержать вторую строку файла.

Метод IO.foreach

Этот метод также возвращает вывод построчно. Разница между методом foreach и методом readlines заключается в том, что метод foreach связан с блоком. Однако, в отличие от метода readlines , метод foreach не возвращает массив. Например –

#!/usr/bin/ruby

IO.foreach("input.txt"){|block| puts block}

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

Переименование и удаление файлов

Вы можете переименовывать и удалять файлы программно с помощью Ruby с помощью методов переименования и удаления .

Ниже приведен пример для переименования существующего файла test1.txt

#!/usr/bin/ruby

# Rename a file from test1.txt to test2.txt
File.rename( "test1.txt", "test2.txt" )

Ниже приведен пример удаления существующего файла test2.txt

#!/usr/bin/ruby

# Delete file test2.txt
File.delete("test2.txt")

Режимы файлов и владение

Используйте метод chmod с маской для изменения режима или списка разрешений / доступа к файлу –

Ниже приведен пример изменения режима существующего файла test.txt на значение маски:

#!/usr/bin/ruby

file = File.new( "test.txt", "w" )
file.chmod( 0755 )

0700

RWX маска для владельца

0400

г для владельца

0200

ж для владельца

0100

х для владельца

0070

RWX маска для группы

0040

г для группы

0020

W для группы

0010

х для группы

0007

RWX маска для других

0004

г для других

0002

ш для других

0001

х для других

4000

Установить идентификатор пользователя при исполнении

2000

Установить идентификатор группы при исполнении

1000

Сохранить замененный текст даже после использования

Запросы файлов

Следующая команда проверяет, существует ли файл перед его открытием:

#!/usr/bin/ruby

File.open("file.rb") if File::exists?( "file.rb" )

Следующая команда запрашивает, является ли файл действительно файлом –

#!/usr/bin/ruby

# This returns either true or false
File.file?( "text.txt" ) 

Следующая команда выясняет, является ли данное имя файла каталогом –

#!/usr/bin/ruby

# a directory
File::directory?( "/usr/local/bin" ) # => true

# a file
File::directory?( "file.rb" ) # => false

Следующая команда определяет, доступен ли файл для чтения, записи или выполнения.

#!/usr/bin/ruby

File.readable?( "test.txt" )   # => true
File.writable?( "test.txt" )   # => true
File.executable?( "test.txt" ) # => false

Следующая команда определяет, имеет ли файл нулевой размер или нет –

#!/usr/bin/ruby

File.zero?( "test.txt" )      # => true

Следующая команда возвращает размер файла –

#!/usr/bin/ruby

File.size?( "text.txt" )     # => 1002

Следующая команда может быть использована для определения типа файла –

#!/usr/bin/ruby

File::ftype( "test.txt" )     # => file

Метод ftype идентифицирует тип файла, возвращая одно из следующих значений: файл, каталог, characterSpecial, blockSpecial, fifo, link, socket или unknown.

Следующая команда может использоваться, чтобы найти, когда файл был создан, изменен или последний раз обращался –

#!/usr/bin/ruby

File::ctime( "test.txt" ) # => Fri May 09 10:06:37 -0700 2008
File::mtime( "text.txt" ) # => Fri May 09 10:44:44 -0700 2008
File::atime( "text.txt" ) # => Fri May 09 10:45:01 -0700 2008

Справочники в Ruby

Все файлы содержатся в разных каталогах, и у Ruby также нет проблем с ними. В то время как класс File обрабатывает файлы, каталоги обрабатываются с помощью класса Dir .

Навигация по каталогам

Чтобы изменить каталог в Ruby-программе, используйте Dir.chdir следующим образом. В этом примере текущий каталог изменяется на / usr / bin .

Dir.chdir("/usr/bin")

Вы можете узнать, что является текущим каталогом с Dir.pwd

puts Dir.pwd # This will return something like /usr/bin

Вы можете получить список файлов и каталогов в определенном каталоге, используя Dir.entries

puts Dir.entries("/usr/bin").join(' ')

Dir.entries возвращает массив со всеми записями в указанном каталоге. Dir.foreach предоставляет ту же функцию –

Dir.foreach("/usr/bin") do |entry|
   puts entry
end

Еще более краткий способ получения списка каталогов – использование метода массива классов Dir –

Dir["/usr/bin/*"]

Создание каталога

Dir.mkdir может использоваться для создания каталогов –

Dir.mkdir("mynewdir")

Вы также можете установить разрешения для нового каталога (не того, который уже существует) с помощью mkdir –

ПРИМЕЧАНИЕ. – Маска 755 устанавливает для владельца прав, группы, мира [любого] значение rwxr-xr-x, где r = чтение, w = запись и x = выполнение.

Dir.mkdir( "mynewdir", 755 )

Удаление каталога

Dir.delete может быть использован для удаления каталога. Dir.unlink и Dir.rmdir выполняют одну и ту же функцию и предоставляются для удобства.

Dir.delete("testdir")

Создание файлов и временных каталогов

Временные файлы – это те, которые могут быть кратко созданы во время выполнения программы, но не являются постоянным хранилищем информации.

Dir.tmpdir предоставляет путь к временному каталогу в текущей системе, хотя метод по умолчанию недоступен. Чтобы сделать Dir.tmpdir доступным, необходимо использовать require ‘tmpdir’.

Вы можете использовать Dir.tmpdir с File.join для создания независимого от платформы временного файла –

require 'tmpdir'
   tempfilename = File.join(Dir.tmpdir, "tingtong")
   tempfile = File.new(tempfilename, "w")
   tempfile.puts "This is a temporary file"
   tempfile.close
   File.delete(tempfilename)

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

require 'tempfile'
   f = Tempfile.new('tingtong')
   f.puts "Hello"
   puts f.path
   f.close

Встроенные функции

Вот встроенные функции ruby ​​для обработки файлов и каталогов:

Класс файла и методы .

Класс Dir и Методы .

Ruby – исключения

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

Программа останавливается, если возникает исключение. Таким образом, исключения используются для обработки ошибок различного типа, которые могут возникнуть во время выполнения программы и предпринять соответствующие действия вместо полной остановки программы.

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

Синтаксис

begin  
# -  
rescue OneTypeOfException  
# -  
rescue AnotherTypeOfException  
# -  
else  
# Other exceptions
ensure
# Always will be executed
end

Все от начала до спасения защищено. Если во время выполнения этого блока кода возникает исключение, управление передается в блок между спасением и завершением .

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

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

пример

Live Demo

#!/usr/bin/ruby

begin
   file = open("/unexistant_file")
   if file
      puts "File opened successfully"
   end
rescue
      file = STDIN
end
print file, "==", STDIN, "\n"

Это даст следующий результат. Вы можете видеть, что STDIN заменяется на файл, потому что открыть не удалось.

#<IO:0xb7d16f84>==#<IO:0xb7d16f84>

Использование оператора повтора

Вы можете перехватить исключение, используя блок восстановления, а затем использовать оператор retry для запуска блока begin с самого начала.

Синтаксис

begin
   # Exceptions raised by this code will 
   # be caught by the following rescue clause
rescue
   # This block will capture all types of exceptions
   retry  # This will move control to the beginning of begin
end

пример

#!/usr/bin/ruby

begin
   file = open("/unexistant_file")
   if file
      puts "File opened successfully"
   end
rescue
   fname = "existant_file"
   retry
end

Ниже приведен поток процесса –

  • Исключение произошло при открытии.
  • Пошел спасать. Fname был переназначен.
  • По повторным попыткам пошли к началу начала.
  • На этот раз файл открывается успешно.
  • Продолжение необходимого процесса.

ПРИМЕЧАНИЕ. – Обратите внимание, что если файл с замененным именем не существует, этот пример кода повторяется бесконечно. Будьте осторожны, если вы используете повтор для процесса исключения.

Использование рейза Statement

Вы можете использовать оператор поднятия, чтобы вызвать исключение. Следующий метод вызывает исключение всякий раз, когда он вызывается. Это второе сообщение будет напечатано.

Синтаксис

raise 

OR

raise "Error Message" 

OR

raise ExceptionType, "Error Message"

OR

raise ExceptionType, "Error Message" condition

Первая форма просто повторно вызывает текущее исключение (или RuntimeError, если нет текущего исключения). Это используется в обработчиках исключений, которым необходимо перехватить исключение перед его передачей.

Вторая форма создает новое исключение RuntimeError , устанавливая его сообщение в заданную строку. Это исключение затем поднимается вверх по стеку вызовов.

Третья форма использует первый аргумент для создания исключения, а затем устанавливает связанное сообщение со вторым аргументом.

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

пример

Live Demo

#!/usr/bin/ruby

begin  
   puts 'I am before the raise.'  
   raise 'An error has occurred.'  
   puts 'I am after the raise.'  
rescue  
   puts 'I am rescued.'  
end  
puts 'I am after the begin block.'  

Это даст следующий результат –

I am before the raise.  
I am rescued.  
I am after the begin block.  

Еще один пример, показывающий использование рейза

Live Demo

#!/usr/bin/ruby

begin  
   raise 'A test exception.'  
rescue Exception => e  
   puts e.message  
   puts e.backtrace.inspect  
end  

Это даст следующий результат –

A test exception.
["main.rb:4"]

Используя обеспечить заявление

Иногда вам нужно гарантировать, что некоторая обработка выполняется в конце блока кода, независимо от того, было ли вызвано исключение. Например, у вас может быть файл, открытый при входе в блок, и вам нужно убедиться, что он закрывается при выходе из блока.

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

Синтаксис

begin 
   #.. process 
   #..raise exception
rescue 
   #.. handle error 
ensure 
   #.. finally ensure execution
   #.. This will always execute.
end

пример

Live Demo

begin
   raise 'A test exception.'
rescue Exception => e
   puts e.message
   puts e.backtrace.inspect
ensure
   puts "Ensuring execution"
end

Это даст следующий результат –

A test exception.
["main.rb:4"]
Ensuring execution

Использование else Statement

Если присутствует условие else , оно идет после пунктов спасения и перед любой гарантией .

Тело предложения else выполняется только в том случае, если основная часть кода не вызывает никаких исключений.

Синтаксис

begin 
   #.. process 
   #..raise exception
rescue 
   # .. handle error
else
   #.. executes if there is no exception
ensure 
   #.. finally ensure execution
   #.. This will always execute.
end

пример

Live Demo

begin
   # raise 'A test exception.'
   puts "I'm not raising exception"
rescue Exception => e
   puts e.message
   puts e.backtrace.inspect
else
   puts "Congratulations-- no errors!"
ensure
   puts "Ensuring execution"
end

Это даст следующий результат –

I'm not raising exception
Congratulations-- no errors!
Ensuring execution

Поднятое сообщение об ошибке может быть записано с помощью $! переменная.

Поймать и бросить

Несмотря на то, что механизм исключений при поднятии и спасении отлично подходит для отказа от выполнения, когда что-то идет не так, иногда приятно иметь возможность выпрыгнуть из глубоко вложенной конструкции во время обычной обработки. Это где ловить и бросать пригодится.

Функция catch определяет блок, помеченный данным именем (это может быть Symbol или String). Блок выполняется нормально, пока не встретится бросок.

Синтаксис

throw :lablename
#.. this will not be executed
catch :lablename do
#.. matching catch will be executed after a throw is encountered.
end

OR

throw :lablename condition
#.. this will not be executed
catch :lablename do
#.. matching catch will be executed after a throw is encountered.
end

пример

В следующем примере команда throw завершает взаимодействие с пользователем, если ‘!’ набирается в ответ на любое приглашение.

def promptAndGet(prompt)
   print prompt
   res = readline.chomp
   throw :quitRequested if res == "!"
   return res
end

catch :quitRequested do
   name = promptAndGet("Name: ")
   age = promptAndGet("Age: ")
   sex = promptAndGet("Sex: ")
   # ..
   # process information
end
promptAndGet("Name:")

Вы должны попробовать вышеуказанную программу на вашем компьютере, потому что она требует ручного взаимодействия. Это даст следующий результат –

Name: Ruby on Rails
Age: 3
Sex: !
Name:Just Ruby

Исключение класса

Стандартные классы и модули Ruby порождают исключения. Все классы исключений образуют иерархию с классом Exception вверху. Следующий уровень содержит семь различных типов –

  • Прерывание
  • NoMemoryError
  • SignalException
  • Ошибка скрипта
  • Стандартная ошибка
  • SystemExit

На этом уровне есть еще одно исключение, Fatal , но интерпретатор Ruby использует его только для внутреннего использования.

И ScriptError, и StandardError имеют ряд подклассов, но нам не нужно вдаваться в подробности здесь. Важно то, что если мы создаем наши собственные классы исключений, они должны быть подклассами либо класса Exception, либо одного из его потомков.

Давайте посмотрим на пример –

class FileSaveError < StandardError
   attr_reader :reason
   def initialize(reason)
      @reason = reason
   end
end

Теперь посмотрите на следующий пример, который будет использовать это исключение:

File.open(path, "w") do |file|
begin
   # Write out the data ...
rescue
   # Something went wrong!
   raise FileSaveError.new($!)
end
end

Важной строкой здесь является повышение FileSaveError.new ($!) . Мы вызываем функцию указывает, что произошло исключение, передавая ему новый экземпляр FileSaveError, причём причина в том, что конкретное исключение вызвало сбой записи данных.

Рубин – Объектно-ориентированный

Ruby – это чисто объектно-ориентированный язык, и все кажется Ruby объектом. Каждое значение в Ruby – это объект, даже самые примитивные вещи: строки, числа и даже true и false. Даже сам класс является объектом, который является экземпляром класса Class . В этой главе вы познакомитесь со всеми основными функциями, связанными с объектно-ориентированным рубином.

Класс используется для указания формы объекта, и он объединяет представление данных и методы для манипулирования этими данными в одном аккуратном пакете. Данные и методы в классе называются членами класса.

Определение класса Ruby

Когда вы определяете класс, вы определяете план для типа данных. На самом деле это не определяет какие-либо данные, но определяет, что означает имя класса, то есть, из чего будет состоять объект класса и какие операции могут быть выполнены с таким объектом.

Определение класса начинается с ключевого слова class, за которым следует имя класса, и заканчивается разделением. Например, мы определили класс Box, используя ключевое слово class следующим образом:

class Box
   code
end

Имя должно начинаться с заглавной буквы, и по соглашению имена, содержащие более одного слова, запускаются вместе с каждым словом, написанным с заглавной буквы, и без разделительных символов (CamelCase).

Определить объекты Ruby

Класс предоставляет чертежи для объектов, поэтому в основном объект создается из класса. Мы объявляем объекты класса, используя ключевое слово new . Следующие операторы объявляют два объекта класса Box –

box1 = Box.new
box2 = Box.new

Метод инициализации

Метод initialize является стандартным методом класса Ruby и работает почти так же, как конструктор в других объектно-ориентированных языках программирования. Метод initialize полезен, когда вы хотите инициализировать некоторые переменные класса во время создания объекта. Этот метод может принимать список параметров и, как и любой другой метод ruby, ему предшествует ключевое слово def, как показано ниже –

class Box
   def initialize(w,h)
      @width, @height = w, h
   end
end

Переменные экземпляра

Переменные экземпляра являются своего рода атрибутами класса и становятся свойствами объектов после создания объектов с использованием класса. Атрибуты каждого объекта назначаются индивидуально и не имеют общего значения с другими объектами. Доступ к ним осуществляется с помощью оператора @ внутри класса, но для доступа к ним вне класса мы используем открытые методы, которые называются методами доступа . Если мы возьмем определенный выше класс Box, то @width и @height являются переменными экземпляра для класса Box.

class Box
   def initialize(w,h)
      # assign instance variables
      @width, @height = w, h
   end
end

Методы доступа и установки

Чтобы сделать переменные доступными извне класса, они должны быть определены в методах доступа , эти методы доступа также известны как методы получения. В следующем примере показано использование методов доступа –

Live Demo

#!/usr/bin/ruby -w

# define a class
class Box
   # constructor method
   def initialize(w,h)
      @width, @height = w, h
   end

   # accessor methods
   def printWidth
      @width
   end

   def printHeight
      @height
   end
end

# create an object
box = Box.new(10, 20)

# use accessor methods
x = box.printWidth()
y = box.printHeight()

puts "Width of the box is : #{x}"
puts "Height of the box is : #{y}"

Когда приведенный выше код выполняется, он дает следующий результат –

Width of the box is : 10
Height of the box is : 20

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

Live Demo

#!/usr/bin/ruby -w

# define a class
class Box
   # constructor method
   def initialize(w,h)
      @width, @height = w, h
   end

   # accessor methods
   def getWidth
      @width
   end
   def getHeight
      @height
   end

   # setter methods
   def setWidth=(value)
      @width = value
   end
   def setHeight=(value)
      @height = value
   end
end

# create an object
box = Box.new(10, 20)

# use setter methods
box.setWidth = 30
box.setHeight = 50

# use accessor methods
x = box.getWidth()
y = box.getHeight()

puts "Width of the box is : #{x}"
puts "Height of the box is : #{y}"

Когда приведенный выше код выполняется, он дает следующий результат –

Width of the box is : 30
Height of the box is : 50

Методы экземпляра

Методы экземпляра также определяются так же, как мы определяем любой другой метод с использованием ключевого слова def, и их можно использовать только с использованием экземпляра класса, как показано ниже. Их функциональные возможности не ограничены доступом к переменным экземпляра, но они также могут сделать намного больше в соответствии с вашими требованиями.

Live Demo

#!/usr/bin/ruby -w

# define a class
class Box
   # constructor method
   def initialize(w,h)
      @width, @height = w, h
   end
   # instance method
   def getArea
      @width * @height
   end
end

# create an object
box = Box.new(10, 20)

# call instance methods
a = box.getArea()
puts "Area of the box is : #{a}"

Когда приведенный выше код выполняется, он дает следующий результат –

Area of the box is : 200

Класс Методы и Переменные

Переменные класса – это переменная, которая используется всеми экземплярами класса. Другими словами, существует один экземпляр переменной, и к ней обращаются экземпляры объекта. Переменные класса начинаются с двух символов @ (@@). Переменная класса должна быть инициализирована в определении класса, как показано ниже.

Метод класса определяется с помощью def self.methodname () , который заканчивается конечным разделителем и вызывается с использованием имени класса в качестве classname.methodname, как показано в следующем примере.

#!/usr/bin/ruby -w

class Box
   # Initialize our class variables
   @@count = 0
   def initialize(w,h)
      # assign instance avriables
      @width, @height = w, h

      @@count += 1
   end

   def self.printCount()
      puts "Box count is : #@@count"
   end
end

# create two object
box1 = Box.new(10, 20)
box2 = Box.new(30, 100)

# call class method to print box count
Box.printCount()

Когда приведенный выше код выполняется, он дает следующий результат –

Box count is : 2

Метод to_s

Любой класс, который вы определяете, должен иметь метод экземпляра to_s для возврата строкового представления объекта. Ниже приведен простой пример представления объекта Box с точки зрения ширины и высоты.

Live Demo

#!/usr/bin/ruby -w

class Box
   # constructor method
   def initialize(w,h)
      @width, @height = w, h
   end
   # define to_s method
   def to_s
      "(w:#@width,h:#@height)"  # string formatting of the object.
   end
end

# create an object
box = Box.new(10, 20)

# to_s method will be called in reference of string automatically.
puts "String representation of box is : #{box}"

Когда приведенный выше код выполняется, он дает следующий результат –

String representation of box is : (w:10,h:20)

Контроль доступа

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

  • Публичные методы – Публичные методы могут быть вызваны кем угодно. Методы общедоступны по умолчанию, за исключением инициализации, которая всегда является закрытой.

  • Частные методы – к закрытым методам нельзя получить доступ или даже посмотреть извне класса. Только методы класса могут получить доступ к закрытым членам.

  • Защищенные методы . Защищенный метод может вызываться только объектами определяющего класса и его подклассов. Доступ хранится в семье.

Публичные методы – Публичные методы могут быть вызваны кем угодно. Методы общедоступны по умолчанию, за исключением инициализации, которая всегда является закрытой.

Частные методы – к закрытым методам нельзя получить доступ или даже посмотреть извне класса. Только методы класса могут получить доступ к закрытым членам.

Защищенные методы . Защищенный метод может вызываться только объектами определяющего класса и его подклассов. Доступ хранится в семье.

Ниже приведен простой пример, демонстрирующий синтаксис всех трех модификаторов доступа:

Live Demo

#!/usr/bin/ruby -w

# define a class
class Box
   # constructor method
   def initialize(w,h)
      @width, @height = w, h
   end

   # instance method by default it is public
   def getArea
      getWidth() * getHeight
   end

   # define private accessor methods
   def getWidth
      @width
   end
   def getHeight
      @height
   end
   # make them private
   private :getWidth, :getHeight

   # instance method to print area
   def printArea
      @area = getWidth() * getHeight
      puts "Big box area is : #@area"
   end
   # make it protected
   protected :printArea
end

# create an object
box = Box.new(10, 20)

# call instance methods
a = box.getArea()
puts "Area of the box is : #{a}"

# try to call protected or methods
box.printArea()

Когда приведенный выше код выполняется, он дает следующий результат. Здесь первый метод вызывается успешно, но второй метод вызвал проблему.

Area of the box is : 200
test.rb:42: protected method `printArea' called for #
<Box:0xb7f11280 @height = 20, @width = 10> (NoMethodError)

Наследование классов

Одним из наиболее важных понятий в объектно-ориентированном программировании является наследование. Наследование позволяет нам определять класс в терминах другого класса, что облегчает создание и поддержку приложения.

Наследование также дает возможность повторно использовать функциональность кода и быстрое время реализации, но, к сожалению, Ruby не поддерживает множественные уровни наследования, но Ruby поддерживает миксины . Миксин подобен специализированной реализации множественного наследования, в которой наследуется только часть интерфейса.

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

Ruby также поддерживает концепцию подклассов, т. Е. Наследование, и следующий пример объясняет эту концепцию. Синтаксис для расширения класса прост. Просто добавьте символ <и имя суперкласса в оператор класса. Например, следующие определяют класс BigBox как подкласс Box

Live Demo

#!/usr/bin/ruby -w

# define a class
class Box
   # constructor method
   def initialize(w,h)
      @width, @height = w, h
   end
   # instance method
   def getArea
      @width * @height
   end
end

# define a subclass
class BigBox < Box

   # add a new instance method
   def printArea
      @area = @width * @height
      puts "Big box area is : #@area"
   end
end

# create an object
box = BigBox.new(10, 20)

# print the area
box.printArea()

Когда приведенный выше код выполняется, он дает следующий результат –

Big box area is : 200

Переопределение методов

Хотя вы можете добавить новую функциональность в производный класс, но иногда вы хотели бы изменить поведение уже определенного метода в родительском классе. Вы можете сделать это, просто сохранив имя метода и переопределив функциональность метода, как показано ниже в примере:

Live Demo

#!/usr/bin/ruby -w

# define a class
class Box
   # constructor method
   def initialize(w,h)
      @width, @height = w, h
   end
   # instance method
   def getArea
      @width * @height
   end
end

# define a subclass
class BigBox < Box

   # change existing getArea method as follows
   def getArea
      @area = @width * @height
      puts "Big box area is : #@area"
   end
end

# create an object
box = BigBox.new(10, 20)

# print the area using overriden method.
box.getArea()

Перегрузка оператора

Мы бы хотели, чтобы оператор + выполнял векторное сложение двух объектов Box, используя +, оператор * для умножения ширины и высоты Box на скаляр и оператор unary – для отрицания ширины и высоты Box. Вот версия класса Box с определенными математическими операторами:

class Box
   def initialize(w,h)     # Initialize the width and height
      @width,@height = w, h
   end

   def +(other)       # Define + to do vector addition
      Box.new(@width + other.width, @height + other.height)
   end

   def -@           # Define unary minus to negate width and height
      Box.new(-@width, -@height)
   end

   def *(scalar)           # To perform scalar multiplication
      Box.new(@width*scalar, @height*scalar)
   end
end

Замораживание объектов

Иногда мы хотим предотвратить изменение объекта. Метод freeze в Object позволяет нам делать это, эффективно превращая объект в константу. Любой объект можно заморозить, вызвав Object.freeze . Замороженный объект не может быть изменен: вы не можете изменить его переменные экземпляра.

Вы можете проверить, заморожен ли данный объект или нет, используя Object.frozen? метод, который возвращает true в случае, если объект заморожен, иначе возвращается ложное значение. Следующий пример проясняет концепцию –

Live Demo

#!/usr/bin/ruby -w

# define a class
class Box
   # constructor method
   def initialize(w,h)
      @width, @height = w, h
   end

   # accessor methods
   def getWidth
      @width
   end
   def getHeight
      @height
   end

   # setter methods
   def setWidth=(value)
      @width = value
   end
   def setHeight=(value)
      @height = value
   end
end

# create an object
box = Box.new(10, 20)

# let us freez this object
box.freeze
if( box.frozen? )
   puts "Box object is frozen object"
else
   puts "Box object is normal object"
end

# now try using setter methods
box.setWidth = 30
box.setHeight = 50

# use accessor methods
x = box.getWidth()
y = box.getHeight()

puts "Width of the box is : #{x}"
puts "Height of the box is : #{y}"

Когда приведенный выше код выполняется, он дает следующий результат –

Box object is frozen object
test.rb:20:in `setWidth=': can't modify frozen object (TypeError)
   from test.rb:39

Константы класса

Вы можете определить константу внутри класса, присвоив переменной числовое или строковое значение, которое определяется без использования @ или @@. По соглашению мы сохраняем имена констант в верхнем регистре.

Как только константа определена, вы не можете изменить ее значение, но вы можете получить доступ к константе непосредственно внутри класса, как переменная, но если вы хотите получить доступ к константе вне класса, вам придется использовать classname :: constant, как показано в Пример ниже.

Live Demo

#!/usr/bin/ruby -w

# define a class
class Box
   BOX_COMPANY = "TATA Inc"
   BOXWEIGHT = 10
   # constructor method
   def initialize(w,h)
      @width, @height = w, h
   end
   # instance method
   def getArea
      @width * @height
   end
end

# create an object
box = Box.new(10, 20)

# call instance methods
a = box.getArea()
puts "Area of the box is : #{a}"
puts Box::BOX_COMPANY
puts "Box weight is: #{Box::BOXWEIGHT}"

Когда приведенный выше код выполняется, он дает следующий результат –

Area of the box is : 200
TATA Inc
Box weight is: 10

Константы класса наследуются и могут быть переопределены как методы экземпляра.

Создать объект с помощью Allocate

Может возникнуть ситуация, когда вы хотите создать объект, не вызывая его конструктор initialize, т.е. используя новый метод, в таком случае вы можете вызвать allocate , который создаст для вас неинициализированный объект, как в следующем примере:

Live Demo

#!/usr/bin/ruby -w

# define a class
class Box
   attr_accessor :width, :height

   # constructor method
   def initialize(w,h)
      @width, @height = w, h
   end

   # instance method
   def getArea
      @width * @height
   end
end

# create an object using new
box1 = Box.new(10, 20)

# create another object using allocate
box2 = Box.allocate

# call instance method using box1
a = box1.getArea()
puts "Area of the box is : #{a}"

# call instance method using box2
a = box2.getArea()
puts "Area of the box is : #{a}"

Когда приведенный выше код выполняется, он дает следующий результат –

Area of the box is : 200
test.rb:14: warning: instance variable @width not initialized
test.rb:14: warning: instance variable @height not initialized
test.rb:14:in `getArea': undefined method `*' 
   for nil:NilClass (NoMethodError) from test.rb:29

Информация о классе

Если определения классов являются исполняемым кодом, это означает, что они выполняются в контексте некоторого объекта: self должно ссылаться на что-то. Давайте выясним, что это.

#!/usr/bin/ruby -w

class Box
   # print class information
   puts "Type of self = #{self.type}"
   puts "Name of self = #{self.name}"
end

Когда приведенный выше код выполняется, он дает следующий результат –

Type of self = Class
Name of self = Box

Это означает, что определение класса выполняется с этим классом в качестве текущего объекта. Это означает, что методы в метаклассе и его суперклассах будут доступны во время выполнения определения метода.

Рубин – Регулярные выражения

Регулярное выражение – это специальная последовательность символов, которая помогает вам сопоставлять или находить другие строки или наборы строк, используя специальный синтаксис, содержащийся в шаблоне.

Литерал регулярного выражения – это шаблон между косыми чертами или между произвольными разделителями, за которыми следует% r, как показано ниже:

Синтаксис

/pattern/
/pattern/im    # option can be specified
%r!/usr/local! # general delimited regular expression

пример

Live Demo

#!/usr/bin/ruby

line1 = "Cats are smarter than dogs";
line2 = "Dogs also like meat";

if ( line1 =~ /Cats(.*)/ )
   puts "Line1 contains Cats"
end
if ( line2 =~ /Cats(.*)/ )
   puts "Line2 contains  Dogs"
end

Это даст следующий результат –

Line1 contains Cats

Модификаторы регулярного выражения

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

Sr.No. Модификатор и описание
1

я

Игнорирует регистр при сопоставлении текста.

2

о

Выполняет # {} интерполяцию только один раз, при первом вычислении литерала регулярного выражения.

3

Икс

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

4

м

Соответствует нескольким строкам, распознавая новые строки как нормальные символы.

5

и, е, с, п

Интерпретирует регулярное выражение как Unicode (UTF-8), EUC, SJIS или ASCII. Если ни один из этих модификаторов не указан, предполагается, что регулярное выражение использует исходную кодировку.

я

Игнорирует регистр при сопоставлении текста.

о

Выполняет # {} интерполяцию только один раз, при первом вычислении литерала регулярного выражения.

Икс

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

м

Соответствует нескольким строкам, распознавая новые строки как нормальные символы.

и, е, с, п

Интерпретирует регулярное выражение как Unicode (UTF-8), EUC, SJIS или ASCII. Если ни один из этих модификаторов не указан, предполагается, что регулярное выражение использует исходную кодировку.

Как и строковые литералы, разделенные символом% Q, Ruby позволяет вам начинать регулярные выражения с% r, за которым следует разделитель по вашему выбору. Это полезно, когда шаблон, который вы описываете, содержит много символов прямой косой черты, от которых вы не хотите выходить –

# Following matches a single slash character, no escape required
%r|/|

# Flag characters are allowed with this syntax, too
%r[</(.*)>]i

Шаблоны регулярных выражений

За исключением управляющих символов, (+?. * ^ $ () [] {} | \) , Все символы совпадают. Вы можете избежать управляющего символа, поставив перед ним обратную косую черту.

^

Соответствует началу строки.

$

Соответствует концу строки.

,

Соответствует любому отдельному символу, кроме новой строки. Использование опции m позволяет ему соответствовать новой строке.

[…]

Соответствует любому отдельному символу в скобках.

[^ …]

Соответствует любому отдельному символу не в скобках

ре *

Соответствует 0 или более вхождений предыдущего выражения.

ре +

Соответствует 1 или более вхождению предыдущего выражения.

повторно?

Соответствует 0 или 1 вхождению предыдущего выражения.

re {n}

Совпадает ровно с числом вхождений предыдущего выражения.

re {n,}

Соответствует n или более вхождений предыдущего выражения.

re {n, m}

Соответствует не менее n и не более m вхождений предшествующего выражения.

| б

Соответствует либо a, либо b.

(ре)

Группирует регулярные выражения и запоминает сопоставленный текст.

(? IMX)

Временно переключает параметры i, m или x в регулярном выражении. Если в скобках, затрагивается только эта область.

(? -imx)

Временно отключает параметры i, m или x в регулярном выражении. Если в скобках, затрагивается только эта область.

(?: re)

Группирует регулярные выражения без запоминания сопоставленного текста.

(? imx: re)

Временно переключает параметры i, m или x в круглых скобках.

(? -imx: re)

Временно отключает параметры i, m или x в скобках.

(? # …)

Комментарий.

(? = re)

Определяет положение с помощью шаблона. Не имеет диапазона.

(?! re)

Определяет положение, используя отрицание шаблона. Не имеет диапазона.

(?> re)

Соответствует независимому образцу без возврата.

\ ш

Соответствует символам слова.

\ W

Соответствует несловесным персонажам.

\ s

Соответствует пробелу. Эквивалентно [\ t \ n \ r \ f].

\ S

Соответствует непробельному пространству.

\ d

Соответствует цифрам. Эквивалентно [0-9].

\ D

Соответствует нецифровым значениям.

\ A

Соответствует началу строки.

\ Z

Соответствует концу строки. Если новая строка существует, она совпадает непосредственно перед новой строкой.

\ г

Соответствует концу строки.

Точки совпадений, где последний матч закончился.

\ б

Соответствует границам слов, когда они выходят за скобки. Соответствует Backspace (0x08) внутри скобок.

\ B

Соответствует несловесным границам.

\ n, \ t и т. д.

Сопоставляет переводы строк, возврат каретки, вкладки и т. Д.

\ 1 … \ 9

Соответствует n-му сгруппированному подвыражению.

\ 10

Соответствует n-му сгруппированному подвыражению, если оно уже найдено. В противном случае относится к восьмеричному представлению кода символа.

Примеры регулярных выражений

/Рубин/

Матчи “Рубин”.

¥

Соответствует знак иены. Многобайтовые символы поддерживаются в Ruby 1.9 и Ruby 1.8.

/ [Rr] убий /

Соответствует “Рубин” или “Рубин”.

/ р [вы] /

Соответствует “ruby” или “rube”.

/ [AEIOU] /

Соответствует любой строчной гласной.

/ [0-9] /

Соответствует любой цифре; такой же как / [0123456789] /.

/ [AZ] /

Соответствует любой строчной букве ASCII.

/ [AZ] /

Соответствует любой прописной букве ASCII.

/ [A-Za-Z0-9] /

Соответствует любому из вышеперечисленного.

/ [^ AEIOU] /

Совпадает с чем угодно, кроме строчной гласной.

/ [^ 0-9] /

Совпадает с чем угодно, кроме цифры.

/./

Соответствует любому символу, кроме новой строки.

/./m

В многострочном режиме также соответствует символу новой строки.

/ \ д /

Соответствует цифре: / [0-9] /.

/ \ D /

Совпадает с нецифровой цифрой: / [^ 0-9] /.

/ \ s /

Соответствует пробелу: / [\ t \ r \ n \ f] /.

/ \ S /

Совпадает без пробелов: / [^ \ t \ r \ n \ f] /.

/ \ ш /

Соответствует одному слову: / [A-Za-z0-9 _] /.

/ \ W /

Соответствует несловесному символу: / [^ A-Za-z0-9 _] /.

/Рубин?/

Соответствует “rub” или “ruby”: y является необязательным.

/Рубин*/

Совпадения “руб” плюс 0 или более лет.

/ рубин + /

Совпадения “руб” плюс 1 или более лет.

/ \ д {3} /

Соответствует ровно 3 цифрам.

/ \ д {3,} /

Соответствует 3 или более цифрам.

/ \ д {3,5} /

Соответствует 3, 4 или 5 цифрам.

Это соответствует наименьшему количеству повторений –

/<.*>/

Жадное повторение: соответствует «<ruby> perl>».

/<.*?>/

Нежадный: соответствует «<ruby>» в «<ruby> perl>».

/ \ D \ D + /

Нет группы: + повторяется \ d

/ (\ D \ d) + /

Сгруппировано: + повторяет \ D \ d пару

/ ([Rr] uby (,)?) + /

Матч “Рубин”, “Рубин, Рубин, Рубин” и др.

Это снова соответствует ранее подобранной группе –

/ ([Rr]) убий & \ 1ails /

Соответствует ruby ​​& rails или Ruby & Rails.

/([‘”])(?:(?!\1).)*\1/

Строка в одинарных или двойных кавычках. \ 1 соответствует любому совпадению 1-й группы. \ 2 соответствует любому совпадению 2-й группы и т. Д.

/ рубин | деревенщина /

Соответствует “ruby” или “rube”.

/ р (у | ль)) /

Совпадает с “рубином” или “рублем”.

/ рубин (+ |!? \) /

за “рубином” следует один или несколько! или один?

Необходимо указать позицию матча.

/ ^ Рубин /

Соответствует “Ruby” в начале строки или внутренней строки.

/ Рубиновые $ /

Соответствует «Ruby» в конце строки или строки.

/ \ ARuby /

Соответствует “Ruby” в начале строки.

/ Рубин \ Z /

Соответствует “Ruby” в конце строки.

/ \ bRuby \ б /

Совпадает с “Рубином” на границе слова.

/ \ brub \ B /

\ B не является границей слова: соответствует “rub” в “rube” и “ruby”, но не в одиночку.

/ Ruby (?! =) /

Совпадает с “Ruby”, если за ним следует восклицательный знак.

/Рубин(?!!)/

Совпадает с “Ruby”, если после него не стоит восклицательный знак.

/ R (? # Комментарий) /

Спички “R”. Все остальное – комментарий.

/ Р (? Я) убий /

Учитывает регистр при сопоставлении «uby».

/ R (I: убий) /

То же, что и выше.

/ р: |) / (у ля?)

Группировать только без создания \ 1 обратной ссылки.

Поиск и замена

Некоторые из наиболее важных методов String, использующие регулярные выражения, – это sub и gsub , а их варианты на месте – sub! и гсуб! ,

Все эти методы выполняют операцию поиска и замены с использованием шаблона Regexp. Sub & Sub! заменяет первое вхождение шаблона и gsub & gsub! заменяет все вхождения.

Sub и gsub возвращают новую строку, оставляя исходную неизмененной где sub! и гсуб! изменить строку, в которой они вызываются.

Ниже приведен пример –

Live Demo

#!/usr/bin/ruby

phone = "2004-959-559 #This is Phone Number"

# Delete Ruby-style comments
phone = phone.sub!(/#.*$/, "")   
puts "Phone Num : #{phone}"

# Remove anything other than digits
phone = phone.gsub!(/\D/, "")    
puts "Phone Num : #{phone}"

Это даст следующий результат –

Phone Num : 2004-959-559
Phone Num : 2004959559

Ниже приведен еще один пример –

Live Demo

#!/usr/bin/ruby

text = "rails are rails, really good Ruby on Rails"

# Change "rails" to "Rails" throughout
text.gsub!("rails", "Rails")

# Capitalize the word "Rails" throughout
text.gsub!(/\brails\b/, "Rails")
puts "#{text}"

Это даст следующий результат –

Rails are Rails, really good Ruby on Rails

Ruby / DBI Tutorial

В этой главе рассказывается, как получить доступ к базе данных с помощью Ruby. Модуль Ruby DBI предоставляет независимый от базы данных интерфейс для сценариев Ruby, аналогичный интерфейсу модуля Perl DBI.

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

DBI может взаимодействовать со следующим –

  • ADO (объекты данных ActiveX)
  • DB2
  • Frontbase
  • Msql
  • MySQL
  • ODBC
  • оракул
  • OCI8 (Oracle)
  • PostgreSQL
  • Прокси-сервер
  • SQLite
  • SQLRelay

Архитектура приложения DBI

DBI не зависит от любой базы данных, доступной в бэкэнде. Вы можете использовать DBI независимо от того, работаете ли вы с Oracle, MySQL или Informix и т. Д. Это ясно из следующей диаграммы архитектуры.

Архитектура Ruby DBI

Общая архитектура для Ruby DBI использует два уровня:

  • Уровень интерфейса базы данных (DBI). Этот уровень не зависит от базы данных и предоставляет набор общих методов доступа, которые используются одинаково, независимо от типа сервера базы данных, с которым вы общаетесь.

  • Уровень драйвера базы данных (DBD). Этот слой зависит от базы данных; разные драйверы обеспечивают доступ к различным ядрам базы данных. Есть один драйвер для MySQL, другой для PostgreSQL, другой для InterBase, другой для Oracle и так далее. Каждый драйвер интерпретирует запросы от уровня DBI и отображает их на запросы, подходящие для данного типа сервера базы данных.

Уровень интерфейса базы данных (DBI). Этот уровень не зависит от базы данных и предоставляет набор общих методов доступа, которые используются одинаково, независимо от типа сервера базы данных, с которым вы общаетесь.

Уровень драйвера базы данных (DBD). Этот слой зависит от базы данных; разные драйверы обеспечивают доступ к различным ядрам базы данных. Есть один драйвер для MySQL, другой для PostgreSQL, другой для InterBase, другой для Oracle и так далее. Каждый драйвер интерпретирует запросы от уровня DBI и отображает их на запросы, подходящие для данного типа сервера базы данных.

Предпосылки

Если вы хотите писать сценарии Ruby для доступа к базам данных MySQL, вам необходимо установить модуль Ruby MySQL.

Этот модуль действует как DBD, как описано выше, и может быть загружен с https://www.tmtm.org/en/mysql/ruby/.

Получение и установка Ruby / DBI

Вы можете скачать и установить модуль Ruby DBI из следующего местоположения –

https://imgur.com/NFEuWe4/embed

Перед началом этой установки убедитесь, что у вас есть права root. Теперь выполните следующие шаги:

Шаг 1

$ tar zxf dbi-0.2.0.tar.gz

Шаг 2

Перейдите в каталог дистрибутива dbi-0.2.0 и настройте его, используя скрипт setup.rb в этом каталоге. Самая общая команда конфигурации выглядит следующим образом, без аргументов после аргумента config. Эта команда настраивает дистрибутив для установки всех драйверов по умолчанию.

$ ruby setup.rb config

Чтобы быть более конкретным, укажите параметр –with, в котором перечислены конкретные части дистрибутива, которые вы хотите использовать. Например, чтобы настроить только основной модуль DBI и драйвер уровня DBD MySQL, введите следующую команду:

$ ruby setup.rb config --with = dbi,dbd_mysql

Шаг 3

Последний шаг – собрать драйвер и установить его с помощью следующих команд:

$ ruby setup.rb setup
$ ruby setup.rb install

Подключение к базе данных

Предполагая, что мы собираемся работать с базой данных MySQL, перед подключением к базе данных убедитесь в следующем:

  • Вы создали базу данных TESTDB.

  • Вы создали РАБОТНИКА в TESTDB.

  • В этой таблице есть поля FIRST_NAME, LAST_NAME, AGE, SEX и INCOME.

  • Идентификатор пользователя “testuser” и пароль “test123” установлены для доступа к TESTDB.

  • Ruby Module DBI правильно установлен на вашем компьютере.

  • Вы прошли учебник по MySQL, чтобы понять основы MySQL.

Вы создали базу данных TESTDB.

Вы создали РАБОТНИКА в TESTDB.

В этой таблице есть поля FIRST_NAME, LAST_NAME, AGE, SEX и INCOME.

Идентификатор пользователя “testuser” и пароль “test123” установлены для доступа к TESTDB.

Ruby Module DBI правильно установлен на вашем компьютере.

Вы прошли учебник по MySQL, чтобы понять основы MySQL.

Ниже приведен пример соединения с базой данных MySQL «TESTDB».

#!/usr/bin/ruby -w

require "dbi"

begin
   # connect to the MySQL server
   dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
   # get server version string and display it
   row = dbh.select_one("SELECT VERSION()")
   puts "Server version: " + row[0]
rescue DBI::DatabaseError => e
   puts "An error occurred"
   puts "Error code:    #{e.err}"
   puts "Error message: #{e.errstr}"
ensure
   # disconnect from server
   dbh.disconnect if dbh
end

При запуске этого скрипта он выдает следующий результат на нашей машине с Linux.

Server version: 5.0.45

Если соединение с источником данных установлено, то дескриптор базы данных возвращается и сохраняется в dbh для дальнейшего использования, в противном случае для dbh устанавливается значение nil, а e.err и e :: errstr возвращают код ошибки и строку ошибки соответственно.

Наконец, перед выходом убедитесь, что соединение с базой данных закрыто и ресурсы освобождены.

ВСТАВИТЬ Операция

Операция INSERT требуется, когда вы хотите создать свои записи в таблице базы данных.

Как только соединение с базой данных установлено, мы готовы создавать таблицы или записи в таблицах базы данных, используя метод do или метод подготовки и выполнения .

Использование do Statement

Утверждения, которые не возвращают строки, могут быть выполнены с помощью вызова метода do database handle. Этот метод принимает строковый аргумент оператора и возвращает количество строк, затронутых оператором.

dbh.do("DROP TABLE IF EXISTS EMPLOYEE")
dbh.do("CREATE TABLE EMPLOYEE (
   FIRST_NAME  CHAR(20) NOT NULL,
   LAST_NAME  CHAR(20),
   AGE INT,  
   SEX CHAR(1),
   INCOME FLOAT )" );

Аналогично, вы можете выполнить инструкцию SQL INSERT, чтобы создать запись в таблице EMPLOYEE.

#!/usr/bin/ruby -w

require "dbi"

begin
   # connect to the MySQL server
   dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
   dbh.do( "INSERT INTO EMPLOYEE(FIRST_NAME, LAST_NAME, AGE, SEX, INCOME)
      VALUES ('Mac', 'Mohan', 20, 'M', 2000)" )
   puts "Record has been created"
   dbh.commit
rescue DBI::DatabaseError => e
   puts "An error occurred"
   puts "Error code:    #{e.err}"
   puts "Error message: #{e.errstr}"
   dbh.rollback
ensure
   # disconnect from server
   dbh.disconnect if dbh
end

Использование подготовить и выполнить

Вы можете использовать методы prepare и execute класса DBI для выполнения оператора SQL через код Ruby.

Создание записи включает следующие шаги:

  • Подготовка оператора SQL с оператором INSERT. Это будет сделано с использованием метода prepare .

  • Выполнение запроса SQL для выбора всех результатов из базы данных. Это будет сделано с помощью метода execute .

  • Выпускать заявление о ручке. Это будет сделано с использованием готового API

  • Если все в порядке, передайте эту операцию, иначе вы сможете откатить всю транзакцию.

Подготовка оператора SQL с оператором INSERT. Это будет сделано с использованием метода prepare .

Выполнение запроса SQL для выбора всех результатов из базы данных. Это будет сделано с помощью метода execute .

Выпускать заявление о ручке. Это будет сделано с использованием готового API

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

Ниже приведен синтаксис для использования этих двух методов:

sth = dbh.prepare(statement)
sth.execute
   ... zero or more SQL operations ...
sth.finish

Эти два метода могут использоваться для передачи значений связывания в операторы SQL. Возможен случай, когда вводимые значения не указаны заранее. В таком случае используются значения привязки. Вместо фактических значений используется знак вопроса ( ? ), А затем фактические значения передаются через API execute ().

Ниже приведен пример создания двух записей в таблице EMPLOYEE:

#!/usr/bin/ruby -w

require "dbi"

begin
   # connect to the MySQL server
   dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
   sth = dbh.prepare( "INSERT INTO EMPLOYEE(FIRST_NAME, LAST_NAME, AGE, SEX, INCOME)
      VALUES (?, ?, ?, ?, ?)" )
   sth.execute('John', 'Poul', 25, 'M', 2300)
   sth.execute('Zara', 'Ali', 17, 'F', 1000)
   sth.finish
   dbh.commit
   puts "Record has been created"
rescue DBI::DatabaseError => e
   puts "An error occurred"
   puts "Error code:    #{e.err}"
   puts "Error message: #{e.errstr}"
   dbh.rollback
ensure
   # disconnect from server
   dbh.disconnect if dbh
end

Если одновременно существует несколько INSERT, то подготовка инструкции, а затем ее выполнение несколько раз в цикле более эффективна, чем вызов do каждый раз в цикле.

ЧИТАЙТЕ Операцию

Чтение Операция с любой базой данных означает получение некоторой полезной информации из базы данных.

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

Выборка записи включает следующие шаги:

  • Подготовка SQL-запроса на основе обязательных условий. Это будет сделано с использованием метода prepare .

  • Выполнение запроса SQL для выбора всех результатов из базы данных. Это будет сделано с помощью метода execute .

  • Получение всех результатов по одному и печать этих результатов. Это будет сделано методом извлечения .

  • Выпускать заявление о ручке. Это будет сделано с использованием метода финиша .

Подготовка SQL-запроса на основе обязательных условий. Это будет сделано с использованием метода prepare .

Выполнение запроса SQL для выбора всех результатов из базы данных. Это будет сделано с помощью метода execute .

Получение всех результатов по одному и печать этих результатов. Это будет сделано методом извлечения .

Выпускать заявление о ручке. Это будет сделано с использованием метода финиша .

Ниже приведена процедура запроса всех записей из таблицы EMPLOYEE с зарплатой более 1000.

#!/usr/bin/ruby -w

require "dbi"

begin
   # connect to the MySQL server
   dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
   sth = dbh.prepare("SELECT * FROM EMPLOYEE WHERE INCOME > ?")
   sth.execute(1000)

   sth.fetch do |row|
   printf "First Name: %s, Last Name : %s\n", row[0], row[1]
   printf "Age: %d, Sex : %s\n", row[2], row[3]
   printf "Salary :%d \n\n", row[4]
end
   sth.finish
rescue DBI::DatabaseError => e
   puts "An error occurred"
   puts "Error code:    #{e.err}"
   puts "Error message: #{e.errstr}"
ensure
   # disconnect from server
   dbh.disconnect if dbh
end

Это даст следующий результат –

First Name: Mac, Last Name : Mohan
Age: 20, Sex : M
Salary :2000

First Name: John, Last Name : Poul
Age: 25, Sex : M
Salary :2300

Есть более короткие методы для извлечения записей из базы данных. Если вам интересно, тогда пройдите « Извлечение результата», в противном случае перейдите к следующему разделу.

Операция обновления

ОБНОВЛЕНИЕ Операция в любой базе данных означает обновление одной или нескольких записей, которые уже доступны в базе данных. Ниже приведена процедура обновления всех записей, имеющих SEX как «M». Здесь мы увеличим ВОЗРАСТ всех мужчин на один год. Это займет три шага –

  • Подготовка SQL-запроса на основе обязательных условий. Это будет сделано с использованием метода prepare .

  • Выполнение запроса SQL для выбора всех результатов из базы данных. Это будет сделано с помощью метода execute .

  • Выпускать заявление о ручке. Это будет сделано с использованием метода финиша .

  • Если все в порядке, передайте эту операцию, в противном случае вы можете откатить всю транзакцию.

Подготовка SQL-запроса на основе обязательных условий. Это будет сделано с использованием метода prepare .

Выполнение запроса SQL для выбора всех результатов из базы данных. Это будет сделано с помощью метода execute .

Выпускать заявление о ручке. Это будет сделано с использованием метода финиша .

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

#!/usr/bin/ruby -w

require "dbi"

begin
   # connect to the MySQL server
   dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
   sth = dbh.prepare("UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = ?")
   sth.execute('M')
   sth.finish
   dbh.commit
rescue DBI::DatabaseError => e
   puts "An error occurred"
   puts "Error code:    #{e.err}"
   puts "Error message: #{e.errstr}"
   dbh.rollback
ensure
   # disconnect from server
   dbh.disconnect if dbh
end

УДАЛЕНИЕ Операция

Операция DELETE требуется, когда вы хотите удалить некоторые записи из вашей базы данных. Ниже описана процедура удаления всех записей из EMPLOYEE, где AGE больше 20. Эта операция будет включать следующие шаги.

  • Подготовка SQL-запроса на основе обязательных условий. Это будет сделано с использованием метода prepare .

  • Выполнение SQL-запроса для удаления необходимых записей из базы данных. Это будет сделано с помощью метода execute .

  • Выпускать заявление о ручке. Это будет сделано с использованием метода финиша .

  • Если все в порядке, передайте эту операцию, в противном случае вы можете откатить всю транзакцию.

Подготовка SQL-запроса на основе обязательных условий. Это будет сделано с использованием метода prepare .

Выполнение SQL-запроса для удаления необходимых записей из базы данных. Это будет сделано с помощью метода execute .

Выпускать заявление о ручке. Это будет сделано с использованием метода финиша .

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

#!/usr/bin/ruby -w

require "dbi"

begin
   # connect to the MySQL server
   dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
   sth = dbh.prepare("DELETE FROM EMPLOYEE WHERE AGE > ?")
   sth.execute(20)
   sth.finish
   dbh.commit
rescue DBI::DatabaseError => e
   puts "An error occurred"
   puts "Error code:    #{e.err}"
   puts "Error message: #{e.errstr}"
   dbh.rollback
ensure
   # disconnect from server
   dbh.disconnect if dbh
end

Выполнение транзакций

Транзакции – это механизм, который обеспечивает согласованность данных. Транзакции должны иметь следующие четыре свойства –

  • Атомарность – либо транзакция завершена, либо ничего не происходит вообще.

  • Согласованность – транзакция должна начинаться в согласованном состоянии и оставлять систему в согласованном состоянии.

  • Изоляция – промежуточные результаты транзакции не видны за пределами текущей транзакции.

  • Долговечность – после совершения транзакции последствия сохраняются даже после сбоя системы.

Атомарность – либо транзакция завершена, либо ничего не происходит вообще.

Согласованность – транзакция должна начинаться в согласованном состоянии и оставлять систему в согласованном состоянии.

Изоляция – промежуточные результаты транзакции не видны за пределами текущей транзакции.

Долговечность – после совершения транзакции последствия сохраняются даже после сбоя системы.

DBI предоставляет два метода для фиксации или отката транзакции. Существует еще один метод под названием транзакция, который можно использовать для реализации транзакций. Есть два простых подхода для реализации транзакций –

Подход I

Первый подход использует методы фиксации и отката DBI для явного подтверждения или отмены транзакции –

dbh['AutoCommit'] = false # Set auto commit to false.
begin
   dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1 WHERE FIRST_NAME = 'John'")
   dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1 WHERE FIRST_NAME = 'Zara'")
   dbh.commit
rescue
   puts "transaction failed"
   dbh.rollback
end
dbh['AutoCommit'] = true

Подход II

Второй подход использует метод транзакции . Это проще, потому что требуется блок кода, содержащий операторы, составляющие транзакцию. Метод транзакции выполняет блок, а затем автоматически выполняет фиксацию или откат в зависимости от того, успешно ли выполняется блок –

dbh['AutoCommit'] = false # Set auto commit to false.
dbh.transaction do |dbh|
   dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1 WHERE FIRST_NAME = 'John'")
   dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1 WHERE FIRST_NAME = 'Zara'")
end
dbh['AutoCommit'] = true

Операция COMMIT

Фиксация – это операция, которая дает зеленый сигнал базе данных для завершения изменений, и после этой операции никакие изменения не могут быть возвращены обратно.

Вот простой пример вызова метода commit .

dbh.commit

ROLLBACK Операция

Если вас не устраивает одно или несколько изменений, и вы хотите полностью отменить эти изменения, используйте метод отката .

Вот простой пример вызова метода отката .

dbh.rollback

Отключение базы данных

Чтобы отключить соединение с базой данных, используйте отключить API.

dbh.disconnect

Если соединение с базой данных закрыто пользователем с помощью метода разъединения, все незавершенные транзакции откатываются DBI. Однако вместо того, чтобы зависеть от каких-либо подробностей реализации DBI, вашему приложению было бы лучше явно вызвать commit или rollback.

Обработка ошибок

Есть много источников ошибок. Вот несколько примеров: синтаксическая ошибка в выполненном операторе SQL, сбой соединения или вызов метода выборки для уже отмененного или законченного дескриптора оператора.

В случае сбоя метода DBI DBI вызывает исключение. Методы DBI могут вызывать любое из нескольких типов исключений, но два наиболее важных класса исключений – это DBI :: InterfaceError и DBI :: DatabaseError .

Объекты исключений этих классов имеют три атрибута с именами err , errstr и state , которые представляют номер ошибки, описательную строку ошибки и стандартный код ошибки. Атрибуты объяснены ниже –

  • err – возвращает целочисленное представление произошедшей ошибки или nil, если это не поддерживается DBD. Например, DBD Oracle возвращает числовую часть сообщения об ошибке ORA-XXXX .

  • errstr – возвращает строковое представление произошедшей ошибки.

  • состояние – возвращает код SQLSTATE возникшей ошибки. SQLSTATE представляет собой строку длиной пять символов. Большинство DBD не поддерживают это и возвращают nil.

err – возвращает целочисленное представление произошедшей ошибки или nil, если это не поддерживается DBD. Например, DBD Oracle возвращает числовую часть сообщения об ошибке ORA-XXXX .

errstr – возвращает строковое представление произошедшей ошибки.

состояние – возвращает код SQLSTATE возникшей ошибки. SQLSTATE представляет собой строку длиной пять символов. Большинство DBD не поддерживают это и возвращают nil.

Вы видели следующий код выше в большинстве примеров –

rescue DBI::DatabaseError => e
   puts "An error occurred"
   puts "Error code:    #{e.err}"
   puts "Error message: #{e.errstr}"
   dbh.rollback
ensure
   # disconnect from server
   dbh.disconnect if dbh
end

Чтобы получить отладочную информацию о том, что делает ваш скрипт во время его выполнения, вы можете включить трассировку. Для этого вы должны сначала загрузить модуль dbi / trace, а затем вызвать метод trace, который управляет режимом трассировки и назначением вывода –

require "dbi/trace"
..............

trace(mode, destination)

Значение режима может быть 0 (выключено), 1, 2 или 3, и назначение должно быть объектом ввода-вывода. Значения по умолчанию: 2 и STDERR соответственно.

Блоки кода с методами

Есть несколько методов, которые создают дескрипторы. Эти методы могут быть вызваны с помощью блока кода. Преимущество использования блока кода вместе с методами состоит в том, что они предоставляют дескриптор для блока кода в качестве его параметра и автоматически очищают дескриптор, когда блок завершается. Есть несколько примеров, чтобы понять концепцию.

  • DBI.connect – этот метод генерирует дескриптор базы данных, и рекомендуется отключить разъединение в конце блока, чтобы отключить базу данных.

  • dbh.prepare – этот метод генерирует дескриптор оператора, и его рекомендуется завершать в конце блока. Внутри блока вы должны вызвать метод execute для выполнения инструкции.

  • dbh.execute – этот метод похож, за исключением того, что нам не нужно вызывать execute внутри блока. Дескриптор оператора выполняется автоматически.

DBI.connect – этот метод генерирует дескриптор базы данных, и рекомендуется отключить разъединение в конце блока, чтобы отключить базу данных.

dbh.prepare – этот метод генерирует дескриптор оператора, и его рекомендуется завершать в конце блока. Внутри блока вы должны вызвать метод execute для выполнения инструкции.

dbh.execute – этот метод похож, за исключением того, что нам не нужно вызывать execute внутри блока. Дескриптор оператора выполняется автоматически.

Пример 1

DBI.connect может взять блок кода, передать ему дескриптор базы данных и автоматически отключить дескриптор в конце блока следующим образом.

dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123") do |dbh|

Пример 2

dbh.prepare может взять блок кода, передать ему дескриптор оператора и автоматически вызвать финиш в конце блока следующим образом.

dbh.prepare("SHOW DATABASES") do |sth|
   sth.execute
   puts "Databases: " + sth.fetch_all.join(", ")
end

Пример 3

dbh.execute может взять блок кода, передать ему дескриптор оператора и автоматически вызвать финиш в конце блока следующим образом:

dbh.execute("SHOW DATABASES") do |sth|
   puts "Databases: " + sth.fetch_all.join(", ")
end

Метод транзакции DBI также принимает блок кода, который был описан выше.

Специфичные для водителя функции и атрибуты

DBI позволяет драйверам базы данных предоставлять дополнительные специфичные для базы данных функции, которые могут вызываться пользователем с помощью метода func любого объекта Handle.

Специфичные для драйвера атрибуты поддерживаются и могут быть установлены или получены с использованием методов [] = или [] .

dbh.func (: creatb, db_name)

Создает новую базу данных.

dbh.func (: dropdb, db_name)

Удаляет базу данных.

dbh.func (: перезагрузка)

Выполняет операцию перезагрузки.

dbh.func (: выключение)

Выключает сервер.

dbh.func (: insert_id) => Fixnum

Возвращает самое последнее значение AUTO_INCREMENT для соединения.

dbh.func (: client_info) => Строка

Возвращает информацию о клиенте MySQL в терминах версии.

dbh.func (: client_version) => Fixnum

Возвращает информацию о клиенте в терминах версии. Это похоже на: client_info, но оно возвращает fixnum вместо sting.

dbh.func (: host_info) => Строка

Возвращает информацию о хосте.

dbh.func (: proto_info) => Fixnum

Возвращает протокол, используемый для связи.

dbh.func (: server_info) => Строка

Возвращает информацию о сервере MySQL в терминах версии.

dbh.func (: stat) => Строка

Возвращает текущее состояние базы данных.

dbh.func (: thread_id) => Fixnum

Возвращает текущий идентификатор потока.

пример

#!/usr/bin/ruby

require "dbi"
begin
   # connect to the MySQL server
   dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123") 
   puts dbh.func(:client_info)
   puts dbh.func(:client_version)
   puts dbh.func(:host_info)
   puts dbh.func(:proto_info)
   puts dbh.func(:server_info)
   puts dbh.func(:thread_id)
   puts dbh.func(:stat)
rescue DBI::DatabaseError => e
   puts "An error occurred"
   puts "Error code:    #{e.err}"
   puts "Error message: #{e.errstr}"
ensure
   dbh.disconnect if dbh
end

Это даст следующий результат –

5.0.45
50045
Localhost via UNIX socket
10
5.0.45
150621
Uptime: 384981  Threads: 1  Questions: 1101078  Slow queries: 4 \
Opens: 324  Flush tables: 1  Open tables: 64  \
Queries per second avg: 2.860

Ruby Web Applications – CGI-программирование

Ruby – язык общего назначения; его нельзя назвать веб-языком вообще. Тем не менее, веб-приложения и веб-инструменты в целом являются одними из наиболее распространенных применений Ruby.

Вы можете не только написать свой собственный SMTP-сервер, FTP-демон или веб-сервер на Ruby, но вы также можете использовать Ruby для более обычных задач, таких как программирование CGI или в качестве замены для PHP.

Пожалуйста, потратьте несколько минут с CGI Programming Tutorial для более подробной информации о CGI Programming.

Написание сценариев CGI

Самый простой скрипт Ruby CGI выглядит так –

Live Demo

#!/usr/bin/ruby

puts "HTTP/1.0 200 OK"
puts "Content-type: text/html\n\n"
puts "<html><body>This is a test</body></html>"

Если вы вызовете этот сценарий test.cgi и загрузите его в Unix-провайдер веб-хостинга с необходимыми разрешениями, вы можете использовать его в качестве CGI-скрипта.

Например, если у вас есть веб-сайт https://www.example.com/, размещенный у поставщика веб-хостинга Linux, и вы загружаете test.cgi в основной каталог и предоставляете ему разрешения на выполнение, тогда посетите https: // www. example.com/test.cgi должен вернуть HTML-страницу с надписью « Это тест» .

Здесь, когда test.cgi запрашивается из веб-браузера, веб-сервер ищет на веб-сайте test.cgi , а затем выполняет его с использованием интерпретатора Ruby. Сценарий Ruby возвращает базовый заголовок HTTP, а затем возвращает базовый документ HTML.

Использование cgi.rb

Ruby поставляется со специальной библиотекой cgi, которая обеспечивает более сложные взаимодействия, чем с предыдущим CGI-скриптом.

Давайте создадим базовый скрипт CGI, который использует cgi –

Live Demo

#!/usr/bin/ruby

require 'cgi'
cgi = CGI.new

puts cgi.header
puts "<html><body>This is a test</body></html>"

Здесь вы создали объект CGI и использовали его для печати строки заголовка.

Обработка форм

Использование класса CGI дает вам доступ к параметрам запроса HTML двумя способами. Предположим, нам дан URL-адрес /cgi-bin/test.cgi?FirstName = Zara & LastName = Ali.

Вы можете получить доступ к параметрам FirstName и LastName, используя CGI # [] напрямую следующим образом:

#!/usr/bin/ruby

require 'cgi'
cgi = CGI.new
cgi['FirstName'] # =>  ["Zara"]
cgi['LastName']  # =>  ["Ali"]

Есть еще один способ доступа к этим переменным формы. Этот код даст вам хэш всех ключей и значений –

#!/usr/bin/ruby

require 'cgi'
cgi = CGI.new
h = cgi.params  # =>  {"FirstName"=>["Zara"],"LastName"=>["Ali"]}
h['FirstName']  # =>  ["Zara"]
h['LastName']   # =>  ["Ali"]

Ниже приведен код для получения всех ключей –

#!/usr/bin/ruby

require 'cgi'
cgi = CGI.new
cgi.keys         # =>  ["FirstName", "LastName"]

Если форма содержит несколько полей с одним и тем же именем, соответствующие значения будут возвращены сценарию в виде массива. Метод доступа [] возвращает только первый из этих.индексов результат метода params, чтобы получить их все.

В этом примере предположим, что форма имеет три поля с именем «name», и мы ввели три имени «Zara», «Huma» и «Nuha» –

#!/usr/bin/ruby

require 'cgi'
cgi = CGI.new
cgi['name']        # => "Zara"
cgi.params['name'] # => ["Zara", "Huma", "Nuha"]
cgi.keys           # => ["name"]
cgi.params         # => {"name"=>["Zara", "Huma", "Nuha"]}

Примечание. Ruby позаботится о методах GET и POST автоматически. Нет отдельного лечения для этих двух разных методов.

Связанная, но базовая форма, которая может отправлять правильные данные, будет иметь HTML-код, например, так:

<html>
   <body>
      <form method = "POST" action = "http://www.example.com/test.cgi">
         First Name :<input type = "text" name = "FirstName" value = "" />
         <br />
         Last Name :<input type = "text" name = "LastName" value = "" /> 
         <input type = "submit" value = "Submit Data" />
      </form>
   </body>
</html>

Создание форм и HTML

CGI содержит огромное количество методов, используемых для создания HTML. Вы найдете один метод для каждого тега. Чтобы включить эти методы, вы должны создать объект CGI, вызвав CGI.new.

Чтобы упростить вложение тегов, эти методы воспринимают свое содержимое как блоки кода. Блоки кода должны возвращать строку , которая будет использоваться в качестве содержимого для тега. Например –

#!/usr/bin/ruby

require "cgi"
cgi = CGI.new("html4")
cgi.out {
   cgi.html {
      cgi.head { "\n"+cgi.title{"This Is a Test"} } +
      cgi.body { "\n"+
         cgi.form {"\n"+
            cgi.hr +
            cgi.h1 { "A Form: " } + "\n"+
            cgi.textarea("get_text") +"\n"+
            cgi.br +
            cgi.submit
         }
      }
   }
}

ПРИМЕЧАНИЕ. – Метод формы класса CGI может принимать параметр метода, который устанавливает метод HTTP (GET, POST и т. Д.), Который будет использоваться при отправке формы. По умолчанию в этом примере используется POST.

Это даст следующий результат –

Content-Type: text/html
Content-Length: 302

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Final//EN">

<HTML>
   <HEAD>
      <TITLE>This Is a Test</TITLE>
   </HEAD>
   <BODY>
      <FORM METHOD = "post" ENCTYPE = "application/x-www-form-urlencoded">
         <HR>
         <H1>A Form: </H1>
         <TEXTAREA COLS = "70" NAME = "get_text" ROWS = "10"></TEXTAREA>
         <BR>
         <INPUT TYPE = "submit">
      </FORM>
   </BODY>
</HTML>

Цитирование строк

При работе с URL-адресами и HTML-кодом необходимо соблюдать осторожность при цитировании определенных символов. Например, символ косой черты (/) имеет особое значение в URL, поэтому его необходимо экранировать, если он не является частью пути.

Например, любая / в части запроса URL-адреса будет переведена в строку% 2F и должна быть переведена обратно в /, чтобы вы могли ее использовать. Пробел и амперсанд также являются специальными символами. Для этого CGI предоставляет подпрограммы CGI.escape и CGI.unescape .

#!/usr/bin/ruby

require 'cgi'
puts CGI.escape(Zara Ali/A Sweet & Sour Girl")

Это даст следующий результат –

Zara+Ali%2FA Sweet+%26+Sour+Girl")

#!/usr/bin/ruby

require 'cgi'
puts CGI.escapeHTML('<h1>Zara Ali/A Sweet & Sour Girl</h1>')

Это даст следующий результат –

&lt;h1&gt;Zara Ali/A Sweet & Sour Girl&lt;/h1&gt;'

Полезные методы в классе CGI

Вот список методов, связанных с классом CGI –

  • Ruby CGI – Методы, относящиеся к стандартной библиотеке CGI.

Ruby CGI – Методы, относящиеся к стандартной библиотеке CGI.

Файлы cookie и сессии

Мы объяснили эти два понятия в разных разделах. Пожалуйста, следуйте разделам –

Ruby CGI Cookies – Как обращаться с CGI Cookies.

Ruby CGI Sessions – Как управлять сессиями CGI.

Серверы веб-хостинга

Вы можете проверить следующую тему в Интернете, чтобы разместить свой сайт на Unix-сервере –

Unix-хостинг

Отправка электронной почты с использованием Ruby – SMTP

Простой протокол передачи почты (SMTP) – это протокол, который обрабатывает отправку электронной почты и маршрутизацию электронной почты между почтовыми серверами.

Ruby предоставляет класс Net :: SMTP для соединения на стороне клиента по протоколу SMTP и предоставляет два метода класса: новый и запуск .

  • Новый принимает два параметра –

    • Имя сервера по умолчанию для localhost.

    • Номер порта по умолчанию для известного порта 25.

  • Метод запуска принимает эти параметры –

    • Сервер – IP-имя SMTP-сервера, по умолчанию localhost.

    • Порт – номер порта, по умолчанию 25.

    • Домен – Домен отправителя почты, по умолчанию ENV [“HOSTNAME”].

    • Учетная запись – Имя пользователя, по умолчанию ноль.

    • Парольпароль пользователя, по умолчанию ноль.

    • Authtype – тип авторизации, по умолчанию – cram_md5 .

Новый принимает два параметра –

Имя сервера по умолчанию для localhost.

Номер порта по умолчанию для известного порта 25.

Метод запуска принимает эти параметры –

Сервер – IP-имя SMTP-сервера, по умолчанию localhost.

Порт – номер порта, по умолчанию 25.

Домен – Домен отправителя почты, по умолчанию ENV [“HOSTNAME”].

Учетная запись – Имя пользователя, по умолчанию ноль.

Парольпароль пользователя, по умолчанию ноль.

Authtype – тип авторизации, по умолчанию – cram_md5 .

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

  • Источник – строка или массив или что-либо, каждый из которых возвращает по одной строке за раз.

  • Отправитель – строка, которая появится в поле « from» электронного письма.

  • Получатели – строка или массив строк, представляющих адресатов получателей.

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

Отправитель – строка, которая появится в поле « from» электронного письма.

Получатели – строка или массив строк, представляющих адресатов получателей.

пример

Вот простой способ отправить одно письмо, используя скрипт Ruby. Попробуйте один раз –

require 'net/smtp'

message = <<MESSAGE_END
From: Private Person <me@fromdomain.com>
To: A Test User <test@todomain.com>
Subject: SMTP e-mail test

This is a test e-mail message.
MESSAGE_END

Net::SMTP.start('localhost') do |smtp|
  smtp.send_message message, 'me@fromdomain.com', 'test@todomain.com'
end

Здесь вы разместили в сообщении основную электронную почту, используя документ, стараясь правильно отформатировать заголовки. Для писем требуются заголовки От , Кому и Тема , отделенные от основной части письма пустой строкой.

Для отправки почты вы используете Net :: SMTP для подключения к SMTP-серверу на локальном компьютере, а затем используете метод send_message вместе с сообщением, адресом от и адресом назначения в качестве параметров (даже если адреса от и до в самой электронной почте они не всегда используются для маршрутизации почты).

Если вы не используете SMTP-сервер на своем компьютере, вы можете использовать Net :: SMTP для связи с удаленным SMTP-сервером. Если вы не используете службу веб-почты (например, Hotmail или Yahoo! Mail), ваш поставщик электронной почты предоставит вам информацию о сервере исходящей почты, которую вы можете предоставить Net :: SMTP, следующим образом:

Net::SMTP.start('mail.your-domain.com')

Эта строка кода подключается к SMTP-серверу через порт 25 mail.your-domain.com без использования имени пользователя или пароля. Если вам нужно, вы можете указать номер порта и другие детали. Например –

Net::SMTP.start('mail.your-domain.com', 
                25, 
                'localhost', 
                'username', 'password' :plain)

Этот пример подключается к SMTP-серверу по адресу mail.your-domain.com, используя имя пользователя и пароль в текстовом формате. Он идентифицирует имя хоста клиента как localhost.

Отправка электронной почты в формате HTML с использованием Ruby

Когда вы отправляете текстовое сообщение с использованием Ruby, весь контент будет обрабатываться как простой текст. Даже если вы включите теги HTML в текстовое сообщение, оно будет отображаться как простой текст, и теги HTML не будут отформатированы в соответствии с синтаксисом HTML. Но в Ruby Net :: SMTP предусмотрена возможность отправки HTML-сообщения как фактического HTML-сообщения.

При отправке сообщения электронной почты вы можете указать версию Mime, тип содержимого и набор символов для отправки электронной почты в формате HTML.

пример

Ниже приведен пример отправки содержимого HTML в виде электронного письма. Попробуйте один раз –

require 'net/smtp'

message = <<MESSAGE_END
From: Private Person <me@fromdomain.com>
To: A Test User <test@todomain.com>
MIME-Version: 1.0
Content-type: text/html
Subject: SMTP e-mail test

This is an e-mail message to be sent in HTML format

<b>This is HTML message.</b>
<h1>This is headline.</h1>
MESSAGE_END

Net::SMTP.start('localhost') do |smtp|
   smtp.send_message message, 'me@fromdomain.com', 'test@todomain.com'
end

Отправка вложений по электронной почте

Для отправки электронного письма со смешанным содержимым необходимо установить заголовок Content-type в multipart / mixed . Тогда разделы текста и вложения могут быть указаны в границах .

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

Прикрепленные файлы должны быть закодированы с помощью функции pack (“m”), чтобы кодирование base64 перед передачей.

пример

Ниже приведен пример, который отправит файл /tmp/test.txt в качестве вложения.

require 'net/smtp'

filename = "/tmp/test.txt"
# Read a file and encode it into base64 format
filecontent = File.read(filename)
encodedcontent = [filecontent].pack("m")   # base64

marker = "AUNIQUEMARKER"
body = <<EOF
This is a test email to send an attachement.
EOF

# Define the main headers.
part1 = <<EOF
From: Private Person <me@fromdomain.net>
To: A Test User <test@todmain.com>
Subject: Sending Attachement
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary = #{marker}
--#{marker}
EOF

# Define the message action
part2 = <<EOF
Content-Type: text/plain
Content-Transfer-Encoding:8bit

#{body}
--#{marker}
EOF

# Define the attachment section
part3 = <<EOF
Content-Type: multipart/mixed; name = \"#{filename}\"
Content-Transfer-Encoding:base64
Content-Disposition: attachment; filename = "#{filename}"

#{encodedcontent}
--#{marker}--
EOF

mailtext = part1 + part2 + part3

# Let's put our code in safe area
begin 
   Net::SMTP.start('localhost') do |smtp|
      smtp.sendmail(mailtext, 'me@fromdomain.net', ['test@todmain.com'])
   end
rescue Exception => e  
   print "Exception occured: " + e  
end  

ПРИМЕЧАНИЕ. – Вы можете указать несколько адресатов внутри массива, но они должны быть разделены запятой.

Ruby – Socket Программирование

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

В Ruby также есть библиотеки, которые предоставляют высокоуровневый доступ к определенным сетевым протоколам прикладного уровня, таким как FTP, HTTP и так далее.

Эта глава дает вам понимание самой известной концепции в сети – Socket Programming.

Что такое сокеты?

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

Сокеты могут быть реализованы для нескольких различных типов каналов: доменные сокеты Unix, TCP, UDP и т. Д. Сокет предоставляет специальные классы для обработки общих транспортов, а также универсальный интерфейс для обработки остальных.

Сокеты имеют свой собственный словарь –

Sr.No. Срок и описание
1

домен

Семейство протоколов, которые будут использоваться в качестве транспортного механизма. Эти значения являются константами, такими как PF_INET, PF_UNIX, PF_X25 и так далее.

2

тип

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

3

протокол

Обычно ноль, это может использоваться для идентификации варианта протокола в домене и типе.

4

имя хоста

Идентификатор сетевого интерфейса –

Строка, которая может быть именем хоста, четырехточечным адресом или IPV6-адресом в двоеточии (и, возможно, точечной) нотации.

Строка “<broadcast>”, которая указывает адрес INADDR_BROADCAST.

Строка нулевой длины, которая указывает INADDR_ANY, или

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

5

порт

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

домен

Семейство протоколов, которые будут использоваться в качестве транспортного механизма. Эти значения являются константами, такими как PF_INET, PF_UNIX, PF_X25 и так далее.

тип

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

протокол

Обычно ноль, это может использоваться для идентификации варианта протокола в домене и типе.

имя хоста

Идентификатор сетевого интерфейса –

Строка, которая может быть именем хоста, четырехточечным адресом или IPV6-адресом в двоеточии (и, возможно, точечной) нотации.

Строка “<broadcast>”, которая указывает адрес INADDR_BROADCAST.

Строка нулевой длины, которая указывает INADDR_ANY, или

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

порт

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

Простой клиент

Здесь мы напишем очень простую клиентскую программу, которая откроет соединение с данным портом и данным хостом. Класс Ruby TCPSocket предоставляет функцию open для открытия такого сокета.

TCPSocket.open (имя хоста, порт) открывает TCP-соединение с именем хоста на порту .

Когда у вас есть открытый сокет, вы можете читать из него, как любой объект ввода-вывода. Когда закончите, не забудьте закрыть его, как вы бы закрыли файл.

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

require 'socket'        # Sockets are in standard library

hostname = 'localhost'
port = 2000

s = TCPSocket.open(hostname, port)

while line = s.gets     # Read lines from the socket
   puts line.chop       # And print with platform line terminator
end
s.close                 # Close the socket when done

Простой сервер

Для написания интернет-серверов мы используем класс TCPServer . Объект TCPServer является фабрикой для объектов TCPSocket.

Теперь вызовите TCPServer.open (имя хоста, функция порта, чтобы указать порт для вашей службы и создать объект TCPServer .

Затем вызовите метод accept возвращенного объекта TCPServer. Этот метод ожидает подключения клиента к указанному вами порту и возвращает объект TCPSocket , представляющий соединение с этим клиентом.

require 'socket'                 # Get sockets from stdlib

server = TCPServer.open(2000)    # Socket to listen on port 2000
loop {                           # Servers run forever
   client = server.accept        # Wait for a client to connect
   client.puts(Time.now.ctime)   # Send the time to the client
   client.puts "Closing the connection. Bye!"
   client.close                  # Disconnect from the client
}

Теперь запустите этот сервер в фоновом режиме, а затем запустите указанный выше клиент, чтобы увидеть результат.

Многопользовательские TCP-серверы

Большинство серверов в Интернете предназначены для одновременной работы с большим количеством клиентов.

Класс Thread в Ruby позволяет легко создавать многопоточный сервер. Он принимает запросы и сразу же создает новый поток выполнения для обработки соединения, позволяя основной программе ожидать больше соединений.

require 'socket'                 # Get sockets from stdlib

server = TCPServer.open(2000)    # Socket to listen on port 2000
loop {                           # Servers run forever
   Thread.start(server.accept) do |client|
   client.puts(Time.now.ctime)   # Send the time to the client
   client.puts "Closing the connection. Bye!"
   client.close                  # Disconnect from the client
   end
}

В этом примере у вас есть постоянный цикл, и когда server.accept отвечает, новый поток создается и запускается немедленно для обработки только что принятого соединения с использованием объекта соединения, переданного в поток. Тем не менее, основная программа немедленно возвращается назад и ждет новых подключений.

Использование потоков Ruby таким образом означает, что код переносим и будет работать одинаково в Linux, OS X и Windows.

Крошечный веб-браузер

Мы можем использовать библиотеку сокетов для реализации любого интернет-протокола. Вот, например, код для извлечения содержимого веб-страницы –

require 'socket'
 
host = 'www.tutorialspoint.com'     # The web server
port = 80                           # Default HTTP port
path = "/index.htm"                 # The file we want 

# This is the HTTP request we send to fetch a file
request = "GET #{path} HTTP/1.0\r\n\r\n"

socket = TCPSocket.open(host,port)  # Connect to server
socket.print(request)               # Send request
response = socket.read              # Read complete response
# Split response at first blank line into headers and body
headers,body = response.split("\r\n\r\n", 2) 
print body                          # And display it

Для реализации аналогичного веб-клиента вы можете использовать готовую библиотеку, такую ​​как Net :: HTTP, для работы с HTTP. Вот код, который делает эквивалент предыдущего кода –

require 'net/http'                  # The library we need
host = 'www.tutorialspoint.com'     # The web server
path = '/index.htm'                 # The file we want 

http = Net::HTTP.new(host)          # Create a connection
headers, body = http.get(path)      # Request the file
if headers.code == "200"            # Check the status code   
   print body                        
else                                
   puts "#{headers.code} #{headers.message}" 
end

Пожалуйста, проверьте похожие библиотеки для работы с протоколами FTP, SMTP, POP и IMAP.

Дальнейшие чтения

Мы дали вам быстрый старт по программированию сокетов. Это большая тема, поэтому рекомендуется изучить библиотеку Ruby Socket и методы классов, чтобы узнать больше.

Ruby – учебник по XML, XSLT и XPath

Что такое XML?

Расширяемый язык разметки (XML) – это язык разметки, очень похожий на HTML или SGML. Это рекомендуется Консорциумом World Wide Web и доступно в качестве открытого стандарта.

XML – это переносимый язык с открытым исходным кодом, который позволяет программистам разрабатывать приложения, которые могут быть прочитаны другими приложениями, независимо от операционной системы и / или языка разработки.

XML чрезвычайно полезен для отслеживания небольших и средних объемов данных, не требуя магистрали на основе SQL.

XML Parser Архитектуры и API

Для синтаксических анализаторов XML доступны два варианта:

  • SAX-like (потоковые интерфейсы) – здесь вы регистрируете обратные вызовы для интересующих событий, а затем позволяете анализатору проходить через документ. Это полезно, когда ваши документы большие или у вас есть ограничения памяти, он анализирует файл, когда читает его с диска, и весь файл никогда не сохраняется в памяти.

  • DOM-like (интерфейсы дерева объектов) – это рекомендация Консорциума World Wide Web, в которой весь файл считывается в память и хранится в иерархической (основанной на дереве) форме для представления всех возможностей документа XML.

SAX-like (потоковые интерфейсы) – здесь вы регистрируете обратные вызовы для интересующих событий, а затем позволяете анализатору проходить через документ. Это полезно, когда ваши документы большие или у вас есть ограничения памяти, он анализирует файл, когда читает его с диска, и весь файл никогда не сохраняется в памяти.

DOM-like (интерфейсы дерева объектов) – это рекомендация Консорциума World Wide Web, в которой весь файл считывается в память и хранится в иерархической (основанной на дереве) форме для представления всех возможностей документа XML.

Очевидно, что SAX не может обрабатывать информацию так же быстро, как DOM при работе с большими файлами. С другой стороны, использование исключительно DOM действительно может убить ваши ресурсы, особенно если они используются для большого количества маленьких файлов.

SAX доступен только для чтения, а DOM позволяет вносить изменения в файл XML. Поскольку эти два разных API буквально дополняют друг друга, нет никаких причин, по которым вы не можете использовать их оба для больших проектов.

Разбор и создание XML с использованием Ruby

Наиболее распространенный способ манипулировать XML – это библиотека REXML Шона Рассела. С 2002 года REXML является частью стандартного дистрибутива Ruby.

REXML – это чистый XML-процессор Ruby, соответствующий стандарту XML 1.0. Это не проверяющий процессор, который проходит все не подтверждающие проверки соответствия OASIS.

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

  • На Ruby написано 100 процентов.
  • Может использоваться как для SAX, так и для DOM-анализа.
  • Это легкий, менее 2000 строк кода.
  • Методы и классы действительно просты для понимания.
  • API на основе SAX2 и полная поддержка XPath.
  • Поставляется с установкой Ruby и не требует отдельной установки.

Для всех наших примеров XML-кода давайте использовать простой XML-файл в качестве входных данных –

<collection shelf = "New Arrivals">
   <movie title = "Enemy Behind">
      <type>War, Thriller</type>
      <format>DVD</format>
      <year>2003</year>
      <rating>PG</rating>
      <stars>10</stars>
      <description>Talk about a US-Japan war</description>
   </movie>
   <movie title = "Transformers">
      <type>Anime, Science Fiction</type>
      <format>DVD</format>
      <year>1989</year>
      <rating>R</rating>
      <stars>8</stars>
      <description>A schientific fiction</description>
   </movie>
   <movie title = "Trigun">
      <type>Anime, Action</type>
      <format>DVD</format>
      <episodes>4</episodes>
      <rating>PG</rating>
      <stars>10</stars>
      <description>Vash the Stampede!</description>
   </movie>
   <movie title = "Ishtar">
      <type>Comedy</type>
      <format>VHS</format>
      <rating>PG</rating>
      <stars>2</stars>
      <description>Viewable boredom</description>
   </movie>
</collection>

DOM-подобный анализ

Давайте сначала проанализируем наши XML-данные в виде дерева . Мы начинаем с требования библиотеки rexml / document ; часто для удобства мы делаем include REXML для импорта в пространство имен верхнего уровня.

#!/usr/bin/ruby -w

require 'rexml/document'
include REXML

xmlfile = File.new("movies.xml")
xmldoc = Document.new(xmlfile)

# Now get the root element
root = xmldoc.root
puts "Root element : " + root.attributes["shelf"]

# This will output all the movie titles.
xmldoc.elements.each("collection/movie"){ 
   |e| puts "Movie Title : " + e.attributes["title"] 
}

# This will output all the movie types.
xmldoc.elements.each("collection/movie/type") {
   |e| puts "Movie Type : " + e.text 
}

# This will output all the movie description.
xmldoc.elements.each("collection/movie/description") {
   |e| puts "Movie Description : " + e.text 
}

Это даст следующий результат –

Root element : New Arrivals
Movie Title : Enemy Behind
Movie Title : Transformers
Movie Title : Trigun
Movie Title : Ishtar
Movie Type : War, Thriller
Movie Type : Anime, Science Fiction
Movie Type : Anime, Action
Movie Type : Comedy
Movie Description : Talk about a US-Japan war
Movie Description : A schientific fiction
Movie Description : Vash the Stampede!
Movie Description : Viewable boredom

SAX-подобный анализ

Чтобы обработать те же данные, фильмы.xml , файл ориентированным на поток способом, мы определим класс слушателя, чьи методы будут являться целью для обратных вызовов от анализатора.

ПРИМЕЧАНИЕ. – Не рекомендуется использовать SAX-подобный синтаксический анализ для небольшого файла, это только для демонстрационного примера.

#!/usr/bin/ruby -w

require 'rexml/document'
require 'rexml/streamlistener'
include REXML

class MyListener
   include REXML::StreamListener
   def tag_start(*args)
      puts "tag_start: #{args.map {|x| x.inspect}.join(', ')}"
   end

   def text(data)
      return if data =~ /^\w*$/     # whitespace only
      abbrev = data[0..40] + (data.length > 40 ? "..." : "")
      puts "  text   :   #{abbrev.inspect}"
   end
end

list = MyListener.new
xmlfile = File.new("movies.xml")
Document.parse_stream(xmlfile, list)

Это даст следующий результат –

tag_start: "collection", {"shelf"=>"New Arrivals"}
tag_start: "movie", {"title"=>"Enemy Behind"}
tag_start: "type", {}
   text   :   "War, Thriller"
tag_start: "format", {}
tag_start: "year", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
   text   :   "Talk about a US-Japan war"
tag_start: "movie", {"title"=>"Transformers"}
tag_start: "type", {}
   text   :   "Anime, Science Fiction"
tag_start: "format", {}
tag_start: "year", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
   text   :   "A schientific fiction"
tag_start: "movie", {"title"=>"Trigun"}
tag_start: "type", {}
   text   :   "Anime, Action"
tag_start: "format", {}
tag_start: "episodes", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
   text   :   "Vash the Stampede!"
tag_start: "movie", {"title"=>"Ishtar"}
tag_start: "type", {}
tag_start: "format", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
   text   :   "Viewable boredom"

XPath и Ruby

Альтернативный способ просмотра XML – это XPath. Это своего рода псевдо-язык, который описывает, как найти конкретные элементы и атрибуты в документе XML, трактуя этот документ как логическое упорядоченное дерево.

REXML имеет поддержку XPath через класс XPath . Он предполагает синтаксический анализ на основе дерева (объектная модель документа), как мы видели выше.

#!/usr/bin/ruby -w

require 'rexml/document'
include REXML

xmlfile = File.new("movies.xml")
xmldoc = Document.new(xmlfile)

# Info for the first movie found
movie = XPath.first(xmldoc, "//movie")
p movie

# Print out all the movie types
XPath.each(xmldoc, "//type") { |e| puts e.text }

# Get an array of all of the movie formats.
names = XPath.match(xmldoc, "//format").map {|x| x.text }
p names

Это даст следующий результат –

<movie title = 'Enemy Behind'> ... </>
War, Thriller
Anime, Science Fiction
Anime, Action
Comedy
["DVD", "DVD", "DVD", "VHS"]

XSLT и Ruby

Существует два парсера XSLT, которые может использовать Ruby. Краткое описание каждого приведено здесь.

Рубин-Sablotron

Этот парсер написан и поддерживается Масаёси Такахаши. Это написано в первую очередь для ОС Linux и требует следующих библиотек –

  • Sablot
  • Iconv
  • эмигрант

Вы можете найти этот модуль на Ruby-Sablotron .

XSLT4R

XSLT4R написан Майклом Нейманом и может быть найден в RAA в разделе Библиотеки в XML. XSLT4R использует простой интерфейс командной строки, хотя его можно альтернативно использовать в стороннем приложении для преобразования XML-документа.

Для работы XSLT4R требуется XMLScan, который включен в архив XSLT4R и который также является 100-процентным модулем Ruby. Эти модули могут быть установлены с использованием стандартного метода установки Ruby (например, ruby ​​install.rb).

XSLT4R имеет следующий синтаксис –

ruby xslt.rb stylesheet.xsl document.xml [arguments]

Если вы хотите использовать XSLT4R из приложения, вы можете включить XSLT и ввести необходимые параметры. Вот пример –

require "xslt"

stylesheet = File.readlines("stylesheet.xsl").to_s
xml_doc = File.readlines("document.xml").to_s
arguments = { 'image_dir' => '/....' }
sheet = XSLT::Stylesheet.new( stylesheet, arguments )

# output to StdOut
sheet.apply( xml_doc )

# output to 'str'
str = ""
sheet.output = [ str ]
sheet.apply( xml_doc )

Дальнейшее чтение

  • Для получения полной информации о REXML Parser, пожалуйста, обратитесь к стандартной документации для REXML Parser Documentation .

  • Вы можете скачать XSLT4R из репозитория RAA .

Для получения полной информации о REXML Parser, пожалуйста, обратитесь к стандартной документации для REXML Parser Documentation .

Вы можете скачать XSLT4R из репозитория RAA .

Веб-сервисы с Ruby – SOAP4R

Что такое SOAP?

Простой протокол доступа к объектам (SOAP) – это кроссплатформенный и независимый от языка протокол RPC, основанный на XML и, как правило (но не обязательно) HTTP.

Он использует XML для кодирования информации, которая делает удаленный вызов процедуры, и HTTP для передачи этой информации по сети от клиентов к серверам и наоборот.

SOAP имеет ряд преимуществ перед другими технологиями, такими как COM, CORBA и т. Д., Например, его относительно дешевые затраты на развертывание и отладку, его расширяемость и простота использования, а также наличие нескольких реализаций для разных языков и платформ.

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

Эта глава знакомит вас с реализацией SOAP для Ruby (SOAP4R). Это базовый учебник, поэтому, если вам нужны глубокие подробности, вам нужно будет обратиться к другим ресурсам.

Установка SOAP4R

SOAP4R – это реализация SOAP для Ruby, разработанная Хироши Накамурой, которую можно загрузить с:

ПРИМЕЧАНИЕ. – Существует большая вероятность того, что вы уже установили этот компонент.

Download SOAP

Если вам известна утилита gem, вы можете использовать следующую команду для установки SOAP4R и связанных пакетов.

$ gem install soap4r --include-dependencies

Если вы работаете в Windows, вам нужно скачать заархивированный файл из вышеуказанного места и установить его, используя стандартный метод установки, запустив ruby install.rb .

Написание серверов SOAP4R

SOAP4R поддерживает два разных типа серверов –

  • На основе CGI / FastCGI (SOAP :: RPC :: CGIStub)
  • Автономный (SOAP :: RPC: StandaloneServer)

В этой главе подробно описывается создание автономного сервера. Следующие шаги участвуют в написании сервера SOAP.

Шаг 1 – Унаследовать класс SOAP :: RPC :: StandaloneServer

Чтобы реализовать свой собственный автономный сервер, вам нужно написать новый класс, который будет дочерним от SOAP :: StandaloneServer, следующим образом:

class MyServer < SOAP::RPC::StandaloneServer
  ...............
end

ПРИМЕЧАНИЕ. – Если вы хотите написать сервер на основе FastCGI, вам нужно принять SOAP :: RPC :: CGIStub в качестве родительского класса, остальная часть процедуры останется прежней.

Шаг 2 – Определите методы обработчика

Второй шаг – написать методы Web-сервисов, которые вы хотели бы представить внешнему миру.

Они могут быть написаны как простые методы Ruby. Например, давайте напишем два метода, чтобы добавить два числа и разделить два числа –

class MyServer < SOAP::RPC::StandaloneServer
   ...............

   # Handler methods
   def add(a, b)
      return a + b
   end
   def div(a, b) 
      return a / b 
   end
end

Шаг 3 – Предоставить методы обработчика

Следующим шагом является добавление определенных методов на наш сервер. Метод initialize используется для предоставления методов обслуживания одним из двух следующих методов:

class MyServer < SOAP::RPC::StandaloneServer
   def initialize(*args)
      add_method(receiver, methodName, *paramArg)
   end
end

Вот описание параметров –

Sr.No. Параметр и описание
1

получатель

Объект, который содержит метод methodName. Вы определяете сервисные методы в том же классе, что и метод methodDef, этот параметр является self .

2

имяМетода

Имя метода, который вызывается из-за запроса RPC.

3

paramArg

Определяет, когда дано, имена параметров и режимы параметров.

получатель

Объект, который содержит метод methodName. Вы определяете сервисные методы в том же классе, что и метод methodDef, этот параметр является self .

имяМетода

Имя метода, который вызывается из-за запроса RPC.

paramArg

Определяет, когда дано, имена параметров и режимы параметров.

Чтобы понять использование параметров inout или out , рассмотрим следующий метод обслуживания, который принимает два параметра (inParam и inoutParam), возвращает одно нормальное возвращаемое значение (retVal) и два дополнительных параметра: inoutParam и outParam

def aMeth(inParam, inoutParam)
   retVal = inParam + inoutParam
   outParam = inParam . inoutParam
   inoutParam = inParam * inoutParam
   return retVal, inoutParam, outParam
end

Теперь мы можем раскрыть этот метод следующим образом:

add_method(self, 'aMeth', [
   %w(in inParam),
   %w(inout inoutParam),
   %w(out outParam),
   %w(retval return)
])

Шаг 4 – Запустите сервер

Последний шаг – запустить ваш сервер, создав один экземпляр производного класса и вызвав метод start .

myServer = MyServer.new('ServerName', 'urn:ruby:ServiceName', hostname, port)

myServer.start

Вот описание обязательных параметров –

Sr.No. Параметр и описание
1

Название сервера

Имя сервера, вы можете дать то, что вам нравится больше всего.

2

Урна: рубин: ServiceName

Здесь urn: ruby является константой, но вы можете дать уникальное имя ServiceName для этого сервера.

3

имя хоста

Указывает имя хоста, на котором будет прослушивать этот сервер.

4

порт

Доступный номер порта, который будет использоваться для веб-службы.

Название сервера

Имя сервера, вы можете дать то, что вам нравится больше всего.

Урна: рубин: ServiceName

Здесь urn: ruby является константой, но вы можете дать уникальное имя ServiceName для этого сервера.

имя хоста

Указывает имя хоста, на котором будет прослушивать этот сервер.

порт

Доступный номер порта, который будет использоваться для веб-службы.

пример

Теперь, используя описанные выше шаги, давайте напишем один автономный сервер –

require "soap/rpc/standaloneserver"

begin
   class MyServer < SOAP::RPC::StandaloneServer

      # Expose our services
      def initialize(*args)
         add_method(self, 'add', 'a', 'b')
         add_method(self, 'div', 'a', 'b')
      end

      # Handler methods
      def add(a, b)
         return a + b
      end
      def div(a, b) 
         return a / b 
      end
end
   server = MyServer.new("MyServer", 
            'urn:ruby:calculation', 'localhost', 8080)
   trap('INT){
      server.shutdown
   }
   server.start
rescue => err
   puts err.message
end

При выполнении это серверное приложение запускает автономный сервер SOAP на локальном хосте и прослушивает запросы на порте 8080. Он предоставляет один метод обслуживания, add и div , который принимает два параметра и возвращает результат.

Теперь вы можете запустить этот сервер в фоновом режиме следующим образом:

$ ruby MyServer.rb&

Написание клиентов SOAP4R

Класс SOAP :: RPC :: Driver обеспечивает поддержку для написания клиентских приложений SOAP. Эта глава описывает этот класс и демонстрирует его использование на основе приложения.

Ниже приведена минимальная информация, необходимая для вызова службы SOAP.

  • URL-адрес службы SOAP (URL-адрес конечной точки SOAP).
  • Пространство имен методов службы (URI пространства имен метода).
  • Наименования сервисных методов и их параметры.

Теперь мы напишем клиент SOAP, который будет вызывать методы службы, определенные в приведенном выше примере, с именами add и div .

Вот основные шаги для создания клиента SOAP.

Шаг 1. Создание экземпляра драйвера SOAP

Мы создаем экземпляр SOAP :: RPC :: Driver , вызывая его новый метод следующим образом:

SOAP::RPC::Driver.new(endPoint, nameSpace, soapAction)

Вот описание обязательных параметров –

Sr.No. Параметр и описание
1

ENDPOINT

URL-адрес сервера SOAP для подключения.

2

NAMESPACE

Пространство имен, используемое для всех RPC, созданных с помощью этого объекта SOAP :: RPC :: Driver.

3

SOAPAction

Значение для поля SOAPAction заголовка HTTP. Если ноль, то по умолчанию используется пустая строка “”.

ENDPOINT

URL-адрес сервера SOAP для подключения.

NAMESPACE

Пространство имен, используемое для всех RPC, созданных с помощью этого объекта SOAP :: RPC :: Driver.

SOAPAction

Значение для поля SOAPAction заголовка HTTP. Если ноль, то по умолчанию используется пустая строка “”.

Шаг 2 – Добавить методы обслуживания

Чтобы добавить метод службы SOAP в SOAP :: RPC :: Driver, мы можем вызвать следующий метод, используя экземпляр SOAP :: RPC :: Driver

driver.add_method(name, *paramArg)

Вот описание параметров –

Sr.No. Параметр и описание
1

название

Имя метода удаленного веб-сервиса.

2

paramArg

Определяет имена параметров удаленных процедур.

название

Имя метода удаленного веб-сервиса.

paramArg

Определяет имена параметров удаленных процедур.

Шаг 3 – вызвать сервис SOAP

Последний шаг заключается в выставлении счета-фактуры на службу SOAP с использованием экземпляра SOAP :: RPC :: Driver следующим образом:

result = driver.serviceMethod(paramArg...)

Здесь serviceMethod – это фактический метод веб-службы, а paramArg … – это параметры списка, которые необходимо передать в метод службы.

пример

Основываясь на вышеуказанных шагах, мы напишем клиент SOAP следующим образом:

#!/usr/bin/ruby -w

require 'soap/rpc/driver'

NAMESPACE = 'urn:ruby:calculation'
URL = 'http://localhost:8080/'

begin
   driver = SOAP::RPC::Driver.new(URL, NAMESPACE)
   
   # Add remote sevice methods
   driver.add_method('add', 'a', 'b')

   # Call remote service methods
   puts driver.add(20, 30)
rescue => err
   puts err.message
end

Дальнейшие чтения

Я объяснил вам только самые основные понятия веб-сервисов с Ruby. Если вы хотите углубиться в детали, перейдите по следующей ссылке, чтобы узнать больше о веб-сервисах с Ruby .

Ruby – Tk Guide

Вступление

Стандартный графический пользовательский интерфейс (GUI) для Ruby – Tk. Tk начинал как графический интерфейс для языка сценариев Tcl, разработанного Джоном Оустерхаутом.

Tk имеет уникальное отличие – единственный кроссплатформенный графический интерфейс. Tk работает на Windows, Mac и Linux и обеспечивает естественный внешний вид для каждой операционной системы.

Основной компонент приложения на основе Tk называется виджетом. Компонент также иногда называют окном, поскольку в Tk «окно» и «виджет» часто используются взаимозаменяемо.

Приложения Tk следуют иерархии виджетов, где любое количество виджетов может быть размещено в другом виджете, а эти виджеты – в другом виджете до бесконечности. Основной виджет в программе Tk называется корневым виджетом и может быть создан путем создания нового экземпляра класса TkRoot.

  • Большинство приложений на основе Tk следуют одному и тому же циклу: создают виджеты, помещают их в интерфейс и, наконец, связывают события, связанные с каждым виджетом, с методом.

  • Есть три менеджера геометрии; place, grid и pack , которые отвечают за управление размером и расположением каждого из виджетов в интерфейсе.

Большинство приложений на основе Tk следуют одному и тому же циклу: создают виджеты, помещают их в интерфейс и, наконец, связывают события, связанные с каждым виджетом, с методом.

Есть три менеджера геометрии; place, grid и pack , которые отвечают за управление размером и расположением каждого из виджетов в интерфейсе.

Монтаж

Привязки Ruby Tk распространяются вместе с Ruby, но Tk – это отдельная установка. Пользователи Windows могут загрузить установку Tk одним щелчком мыши из ActiveScl ActiveState .

Пользователям Mac и Linux может и не понадобиться устанавливать его, потому что есть большая вероятность, что он уже установлен вместе с ОС, но если нет, вы можете загрузить готовые пакеты или получить исходный код из Tcl Developer Xchange .

Простое приложение Tk

Типичная структура для программ Ruby / Tk – это создание главного или корневого окна (экземпляр TkRoot), добавление к нему виджетов для создания пользовательского интерфейса, а затем запуск цикла основного события путем вызова Tk.mainloop .

Традиционный Привет, Мир! пример для Ruby / Tk выглядит примерно так –

require 'tk'

root = TkRoot.new { title "Hello, World!" }
TkLabel.new(root) do
   text 'Hello, World!'
   pack { padx 15 ; pady 15; side 'left' }
end
Tk.mainloop

Здесь, после загрузки модуля расширения tk, мы создаем фрейм корневого уровня, используя TkRoot.new . Затем мы создаем виджет TkLabel как дочерний элемент корневого фрейма, устанавливая несколько параметров для метки. Наконец, мы упаковываем корневой фрейм и входим в основной цикл событий GUI.

Если вы запустите этот скрипт, он даст следующий результат –

Ruby / Tk Hello World

Классы Ruby / Tk Widget

Существует список различных классов Ruby / Tk, которые можно использовать для создания желаемого GUI с использованием Ruby / Tk.

  • TkFrame Создает и манипулирует виджетами фреймов.

  • TkButton Создает и манипулирует виджетами кнопок.

  • TkLabel Создает и манипулирует виджетами надписей .

  • TkEntry Создает и управляет входными виджетами.

  • TkCheckButton Создает и манипулирует виджетами с кнопками.

  • TkRadioButton Создает и управляет виджетами радиокнопок.

  • TkListbox Создает и управляет виджетами списка.

  • TkComboBox Создает и управляет виджетами списка.

  • TkMenu Создает и управляет виджетами меню.

  • TkMenubutton Создает виджеты меню и управляет ими.

  • Tk.messageBox Создает и манипулирует диалоговым окном сообщения.

  • TkScrollbar Создает и манипулирует виджетами полосы прокрутки.

  • TkCanvas Создает и управляет виджетами холста.

  • TkScale Создает и манипулирует масштабными виджетами.

  • TkText Создает и манипулирует текстовыми виджетами.

  • TkToplevel Создает и управляет виджетами верхнего уровня.

  • TkSpinbox Создает и управляет виджетами Spinbox.

  • TkProgressBar Создает и манипулирует виджетами индикатора выполнения.

  • Диалоговое окно Создание и управление виджетами диалогового окна.

  • Tk :: Tile :: Notebook Отображение нескольких окон в ограниченном пространстве с метафорой ноутбука.

  • Tk :: Tile :: Paned Отображает количество подокон, сложенных вертикально или горизонтально.

  • Tk :: Tile :: Separator Отображает горизонтальный или вертикальный разделитель.

  • Шрифт Ruby / Tk, цвета и изображения Общие сведения о шрифтах Ruby / Tk, цвета и изображения

TkFrame Создает и манипулирует виджетами фреймов.

TkButton Создает и манипулирует виджетами кнопок.

TkLabel Создает и манипулирует виджетами надписей .

TkEntry Создает и управляет входными виджетами.

TkCheckButton Создает и манипулирует виджетами с кнопками.

TkRadioButton Создает и управляет виджетами радиокнопок.

TkListbox Создает и управляет виджетами списка.

TkComboBox Создает и управляет виджетами списка.

TkMenu Создает и управляет виджетами меню.

TkMenubutton Создает виджеты меню и управляет ими.

Tk.messageBox Создает и манипулирует диалоговым окном сообщения.

TkScrollbar Создает и манипулирует виджетами полосы прокрутки.

TkCanvas Создает и управляет виджетами холста.

TkScale Создает и манипулирует масштабными виджетами.

TkText Создает и манипулирует текстовыми виджетами.

TkToplevel Создает и управляет виджетами верхнего уровня.

TkSpinbox Создает и управляет виджетами Spinbox.

TkProgressBar Создает и манипулирует виджетами индикатора выполнения.

Диалоговое окно Создание и управление виджетами диалогового окна.

Tk :: Tile :: Notebook Отображение нескольких окон в ограниченном пространстве с метафорой ноутбука.

Tk :: Tile :: Paned Отображает количество подокон, сложенных вертикально или горизонтально.

Tk :: Tile :: Separator Отображает горизонтальный или вертикальный разделитель.

Шрифт Ruby / Tk, цвета и изображения Общие сведения о шрифтах Ruby / Tk, цвета и изображения

Стандартные параметры конфигурации

Все виджеты имеют ряд различных параметров конфигурации, которые обычно управляют тем, как они отображаются или как они ведут себя. Доступные параметры зависят от класса виджета.

Вот список всех стандартных параметров конфигурации, которые могут быть применимы к любому виджету Ruby / Tk.

activebackground => Строка

Определяет цвет фона для использования при рисовании активных элементов. Элемент активен, если курсор мыши расположен над элементом, и нажатие кнопки мыши вызовет некоторое действие. Вы можете использовать названия цветов, такие как «красный», «синий», «розовый», «желтый» и т. Д.

activeborderwidth => Целое число

Указывает неотрицательное значение, указывающее ширину трехмерной границы, нарисованной вокруг активных элементов.

activeforeground => Строка

Определяет цвет переднего плана для использования при рисовании активных элементов.

якорь => Строка

Определяет, как информация в виджете (например, текст или растровое изображение) должна отображаться в виджете. Должно быть одно из значений n , ne , e , se , s , sw , w , nw или center . Например, nw означает отображение информации таким образом, чтобы ее верхний левый угол находился в верхнем левом углу виджета.

background или bg => String

Определяет нормальный цвет фона, используемый при отображении виджета.

bitmap => Bitmap

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

borderwidth или bd => Integer

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

составной => Строка

Указывает, должен ли виджет отображать текст и растровые изображения / изображения одновременно, и если да, то где растровое изображение / изображение должны быть размещены относительно текста. Должно быть одно из значений none , bottom , top , left , right или center .

курсор => строка

Указывает курсор мыши, который будет использоваться для виджета. Возможные значения: «смотреть», «стрелка» и т. Д.

disabledforeground => Строка

Определяет цвет переднего плана для использования при рисовании отключенного элемента.

exportselection => Булево

Определяет, должен ли выбор в виджете также быть X-выбором. Значение может иметь любое из значений true , false , 0 , 1 , yes или no . Если выборка экспортируется, то выбор в виджете отменяет текущий выбор X, выбор вне виджета отменяет выбор любого виджета, и виджет будет отвечать на запросы поиска выбора, когда у него есть выбор.

font => String

Указывает шрифт, который будет использоваться при рисовании текста внутри виджета.

передний план или fg => строка

Определяет обычный цвет переднего плана для использования при отображении виджета.

highlightbackground => Строка

Определяет цвет для отображения в области выделения обхода, когда виджет не имеет фокуса ввода.

highlightcolor => String

Определяет цвет, который будет использоваться для прямоугольника выделения обхода, который рисуется вокруг виджета, когда он имеет фокус ввода.

highlightthickness => Целое число

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

изображение => изображение

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

jump => String

Для виджетов с ползунком, который можно перетаскивать для настройки значения, например полосы прокрутки и шкалы, этот параметр определяет, когда создаются уведомления об изменениях значения. Значение параметра должно быть логическим. Если значение равно false, обновления производятся непрерывно при перемещении ползунка. Если значение равно true, обновления задерживаются до тех пор, пока не будет отпущена кнопка мыши, чтобы завершить перетаскивание; в этот момент делается одно уведомление.

justify => String

Когда в виджете отображается несколько строк текста, этот параметр определяет, как линии выстраиваются в линию друг с другом. Должно быть одним из слева , в центре или справа . Левый означает, что все левые края линий выровнены, центр означает, что центры линий выровнены, а правый означает, что правые края линий выровнены.

смещение => Строка

Определяет смещение тайлов (см. Также опцию тайлов ). Он может иметь два различных формата смещения x, y или сторону смещения , где сторона может быть n , ne , e , se , s , sw , w , nw или center .

orient => String

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

padx => Integer

Указывает неотрицательное значение, указывающее, сколько дополнительного пространства нужно запрашивать для виджета в направлении X.

pady => Целое число

Указывает неотрицательное значение, указывающее, сколько дополнительного пространства нужно запрашивать для виджета в направлении Y.

рельеф => целое число

Указывает трехмерный эффект, необходимый для виджета. Допустимые значения: приподнятый , утопленный , плоский , ребристый и желобчатый

repeatdelay => Integer

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

repeatinterval => Integer

Используется совместно с repeatdelay : после запуска автоповтора этот параметр определяет количество миллисекунд между автоповторами

selectbackground => String

Определяет цвет фона, используемый при отображении выбранных элементов.

selectborderwidth => Целое число

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

selectforeground => String

Определяет цвет переднего плана для использования при отображении выбранных элементов.

setgrid => логическое значение

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

takefocus => Integer

Предоставляет информацию, используемую при перемещении фокуса от окна к окну с помощью обхода клавиатуры (например, Tab и Shift-Tab). Перед установкой фокуса на окно, сценарии обхода сначала проверяют, является ли окно видимым (оно и все его предки отображаются); если нет, окно пропускается. Значение 0 означает, что это окно должно быть полностью пропущено во время обхода клавиатуры. 1 означает, что это окно всегда должно получать фокус ввода.

текст => строка

Определяет строку, которая будет отображаться внутри виджета. Способ отображения строки зависит от конкретного виджета и может определяться другими параметрами, такими как привязка или выравнивание .

textvariable => переменная

Определяет имя переменной. Значением переменной является текстовая строка, которая будет отображаться внутри виджета; если значение переменной изменится, виджет автоматически обновится, чтобы отразить новое значение. Способ отображения строки в виджете зависит от конкретного виджета и может определяться другими параметрами, такими как привязка или выравнивание .

плитка => Изображение

Определяет изображение, используемое для отображения виджета. Если изображение – пустая строка, то отображается нормальный цвет фона.

troughcolor => String

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

troughtile => изображение

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

подчеркивание => целое число

Задает целочисленный индекс символа, который следует подчеркнуть в виджете. Эта опция используется привязками по умолчанию для реализации обхода клавиатуры для кнопок меню и пунктов меню. 0 соответствует первому символу текста, отображаемого в виджете, 1 – следующему символу и т. Д.

обертка => целое число

Для виджетов, которые могут выполнять перенос слов, эта опция указывает максимальную длину строки.

xscrollcommand => функция

Определяет обратный вызов, используемый для связи с горизонтальными полосами прокрутки.

yscrollcommand => функция

Определяет обратный вызов, используемый для связи с вертикальными полосами прокрутки.

Ruby / Tk Geometry Management

Geometry Management имеет дело с позиционированием различных виджетов согласно требованию. Управление геометрией в Tk основывается на концепции главных и подчиненных виджетов.

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

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

Есть три менеджера геометрии , сетка и пакет , которые отвечают за управление размером и расположением каждого из виджетов в интерфейсе.

  • grid Менеджер геометрии, который размещает виджеты в сетке.

  • pack Geometry manager, который упаковывает края ребер.

  • Размещение Geometry Manager для фиксированного размещения или размещения резиновых листов.

grid Менеджер геометрии, который размещает виджеты в сетке.

pack Geometry manager, который упаковывает края ребер.

Размещение Geometry Manager для фиксированного размещения или размещения резиновых листов.

Обработка событий Ruby / Tk

Ruby / Tk поддерживает цикл обработки событий , который получает события из операционной системы. Это такие вещи, как нажатия кнопок, нажатие клавиш, движение мыши, изменение размера окна и т. Д.

Ruby / Tk позаботится об управлении этим циклом событий для вас. Он выяснит, к какому виджету применимо событие (нажал ли пользователь на эту кнопку? Если была нажата клавиша, какое текстовое поле имело фокус?), И отправил его соответствующим образом. Отдельные виджеты знают, как реагировать на события, поэтому, например, кнопка может изменить цвет при наведении на нее курсора мыши и вернуться назад, когда мышь уйдет.

На более высоком уровне Ruby / Tk вызывает в вашей программе обратные вызовы, чтобы указать, что с виджетом произошло что-то существенное. В любом случае вы можете предоставить блок кода или объект Ruby Proc, который определяет, как приложение реагирует на событие или обратный вызов.

Давайте посмотрим, как использовать метод bind, чтобы связать основные системные события окна с процедурами Ruby, которые их обрабатывают. Простейшая форма связывания принимает в качестве входных данных строку, обозначающую имя события и кодовый блок, который Tk использует для обработки события.

Например, чтобы поймать событие ButtonRelease для первой кнопки мыши в каком-либо виджете, вы должны написать:

someWidget.bind('ButtonRelease-1') {
   ....code block to handle this event...
}

Имя события может включать в себя дополнительные модификаторы и детали. Модификатор – это строка типа Shift , Control или Alt , указывающая, что была нажата одна из клавиш-модификаторов.

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

someWidget.bind('Control-ButtonPress-3', proc { puts "Ouch!" })

Многие виджеты Ruby / Tk могут вызывать обратные вызовы, когда пользователь активирует их, и вы можете использовать команду обратного вызова, чтобы указать, что определенный блок кода или процедура вызывается, когда это происходит. Как было показано ранее, вы можете указать процедуру обратного вызова команды при создании виджета –

helpButton = TkButton.new(buttonFrame) {
   text "Help"
   command proc { showHelp }
}

Или вы можете назначить его позже, используя метод команды виджета –

helpButton.command proc { showHelp }

Поскольку командный метод принимает либо процедуры, либо блоки кода, вы также можете написать предыдущий пример кода как –

helpButton = TkButton.new(buttonFrame) {
   text "Help"
   command { showHelp }
}

«1» (один)

Щелкнул левой кнопкой мыши.

“ButtonPress-1”

Щелкнул левой кнопкой мыши.

“Войти”

Перемещена мышь внутри.

“Покидать”

Вытащили мышь наружу.

“Double-1”

Дважды щелкнул.

“B3-Motion”

Перетащите правую кнопку из одной позиции в другую.

Control-ButtonPress-3

Правая кнопка нажата вместе с клавишей Ctrl .

Alt-ButtonPress-1

Пусть кнопка нажата вместе с Alt Key.

Метод настройки

Метод configure можно использовать для установки и получения любых значений конфигурации виджета. Например, чтобы изменить ширину кнопки, вы можете вызвать метод configure в любое время следующим образом:

require "tk"

button = TkButton.new {
   text 'Hello World!'
   pack
}
button.configure('activebackground', 'blue')
Tk.mainloop

Чтобы получить значение для текущего виджета, просто укажите его без значения следующим образом:

color = button.configure('activebackground')

Вы также можете вызвать configure без каких-либо параметров, что даст вам список всех параметров и их значений.

Метод cget

Для простого получения значения параметра, configure возвращает больше информации, чем вы обычно хотите. Метод cget возвращает только текущее значение.

color = button.cget('activebackground')

Ruby – учебник LDAP

Ruby / LDAP – это библиотека расширений для Ruby. Он предоставляет интерфейс для некоторых библиотек LDAP, таких как OpenLDAP, UMich LDAP, Netscape SDK, ActiveDirectory.

Общий API для разработки приложений описан в RFC1823 и поддерживается Ruby / LDAP.

Установка Ruby / LDAP

Вы можете скачать и установить полный пакет Ruby / LDAP с SOURCEFORGE.NET .

Перед установкой Ruby / LDAP убедитесь, что у вас есть следующие компоненты –

  • Ruby 1.8.x (как минимум 1.8.2, если вы хотите использовать ldap / control).
  • OpenLDAP, Netscape SDK, Windows 2003 или Windows XP.

Теперь вы можете использовать стандартный метод установки Ruby. Перед началом, если вы хотите увидеть доступные опции для extconf.rb, запустите его с параметром –help.

$ ruby extconf.rb [--with-openldap1|--with-openldap2| \
                   --with-netscape|--with-wldap32]
$ make
$ make install

ПРИМЕЧАНИЕ. – Если вы собираете программное обеспечение для Windows, вам может потребоваться использовать nmake вместо make .

Установите соединение LDAP

Это двухэтапный процесс –

Шаг 1 – Создание объекта подключения

Ниже приведен синтаксис для создания соединения с каталогом LDAP.

LDAP::Conn.new(host = 'localhost', port = LDAP_PORT)
  • host – это идентификатор хоста, на котором работает каталог LDAP. Мы примем это как localhost .

  • порт – это порт, используемый для службы LDAP. Стандартные порты LDAP – 636 и 389. Убедитесь, какой порт используется на вашем сервере, иначе вы можете использовать LDAP :: LDAP_PORT.

host – это идентификатор хоста, на котором работает каталог LDAP. Мы примем это как localhost .

порт – это порт, используемый для службы LDAP. Стандартные порты LDAP – 636 и 389. Убедитесь, какой порт используется на вашем сервере, иначе вы можете использовать LDAP :: LDAP_PORT.

Этот вызов возвращает новое соединение LDAP :: Conn с сервером, хостом , портом порта .

Шаг 2 – Связывание

Здесь мы обычно указываем имя пользователя и пароль, которые будем использовать до конца сеанса.

Ниже приведен синтаксис для привязки соединения LDAP с использованием DN, dn , учетных данных, pwd и метода связывания, метод

conn.bind(dn = nil, password = nil, method = LDAP::LDAP_AUTH_SIMPLE)do
....
end

Вы можете использовать тот же метод без блока кода. В этом случае вам необходимо явно отсоединить соединение следующим образом:

conn.bind(dn = nil, password = nil, method = LDAP::LDAP_AUTH_SIMPLE)
....
conn.unbind

Если задан кодовый блок, self передается блоку.

Теперь мы можем выполнять операции поиска, добавления, изменения или удаления внутри блока метода bind (между bind и unbind), если у нас есть соответствующие разрешения.

пример

Предполагая, что мы работаем на локальном сервере, давайте соединим вещи с соответствующим хостом, доменом, идентификатором пользователя и паролем и т. Д.

#/usr/bin/ruby -w

require 'ldap'

$HOST =    'localhost'
$PORT =    LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

conn = LDAP::Conn.new($HOST, $PORT)
conn.bind('cn = root, dc = localhost, dc = localdomain','secret')
....
conn.unbind

Добавление записи LDAP

Добавление записи LDPA является двухэтапным процессом –

Шаг 1 – Создание объекта LDAP :: Mod

Чтобы создать запись, нам нужно передать объект LDAP :: Mod в метод conn.add . Вот простой синтаксис для создания объекта LDAP :: Mod

Mod.new(mod_type, attr, vals)
  • mod_type – одна или несколько опций LDAP_MOD_ADD, LDAP_MOD_REPLACE или LDAP_MOD_DELETE.

  • attr – должно быть именем атрибута, с которым нужно работать.

  • vals – это массив значений, относящихся к attr . Если vals содержит двоичные данные, mod_type должен быть логически ИЛИ (|) с LDAP_MOD_BVALUES.

mod_type – одна или несколько опций LDAP_MOD_ADD, LDAP_MOD_REPLACE или LDAP_MOD_DELETE.

attr – должно быть именем атрибута, с которым нужно работать.

vals – это массив значений, относящихся к attr . Если vals содержит двоичные данные, mod_type должен быть логически ИЛИ (|) с LDAP_MOD_BVALUES.

Этот вызов возвращает объект LDAP :: Mod , который может быть передан методам в классе LDAP :: Conn, таким как Conn # add, Conn # add_ext, Conn # modify и Conn # modify_ext.

Шаг 2 – Вызов метода conn.add

Когда мы будем готовы с объектом LDAP :: Mod , мы можем вызвать метод conn.add для создания записи. Вот синтаксис для вызова этого метода –

conn.add(dn, attrs)

Этот метод добавляет запись с DN, dn и атрибутами, attrs . Здесь attrs должен быть либо массивом объектов LDAP :: Mod, либо хэшем пар массивов атрибут / значение.

пример

Вот полный пример, который создаст две записи каталога –

#/usr/bin/ruby -w

require 'ldap'

$HOST =    'localhost'
$PORT =    LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

conn = LDAP::Conn.new($HOST, $PORT)
conn.bind('cn = root, dc = localhost, dc = localdomain','secret')

conn.perror("bind")
entry1 = [
   LDAP.mod(LDAP::LDAP_MOD_ADD,'objectclass',['top','domain']),
   LDAP.mod(LDAP::LDAP_MOD_ADD,'o',['TTSKY.NET']),
   LDAP.mod(LDAP::LDAP_MOD_ADD,'dc',['localhost']),
]

entry2 = [
   LDAP.mod(LDAP::LDAP_MOD_ADD,'objectclass',['top','person']),
   LDAP.mod(LDAP::LDAP_MOD_ADD, 'cn', ['Zara Ali']),
   LDAP.mod(LDAP::LDAP_MOD_ADD | LDAP::LDAP_MOD_BVALUES, 'sn', 
                     ['ttate','ALI', "zero\000zero"]),
]

begin
   conn.add("dc = localhost, dc = localdomain", entry1)
   conn.add("cn = Zara Ali, dc = localhost, dc =  localdomain", entry2)
rescue LDAP::ResultError
   conn.perror("add")
   exit
end
conn.perror("add")
conn.unbind

Изменение записи LDAP

Изменение записи аналогично добавлению. Просто вызовите метод модификации вместо add с атрибутами для модификации. Вот простой синтаксис метода модификации .

conn.modify(dn, mods)

Этот метод изменяет запись с DN, dn и атрибутами, модами . Здесь моды должны быть либо массивом объектов LDAP :: Mod, либо хэшем пар массивов атрибут / значение.

пример

Чтобы изменить фамилию записи, которую мы добавили в предыдущем разделе, мы написали бы:

#/usr/bin/ruby -w

require 'ldap'

$HOST =    'localhost'
$PORT =    LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

conn = LDAP::Conn.new($HOST, $PORT)
conn.bind('cn = root, dc = localhost, dc = localdomain','secret')

conn.perror("bind")
entry1 = [
   LDAP.mod(LDAP::LDAP_MOD_REPLACE, 'sn', ['Mohtashim']),
]

begin
   conn.modify("cn = Zara Ali, dc = localhost, dc = localdomain", entry1)
rescue LDAP::ResultError
   conn.perror("modify")
   exit
end
conn.perror("modify")
conn.unbind

Удаление записи LDAP

Чтобы удалить запись, вызовите метод delete с отличительным именем в качестве параметра. Вот простой синтаксис метода удаления .

conn.delete(dn)

Этот метод удаляет запись с DN, dn .

пример

Чтобы удалить запись Zara Mohtashim , которую мы добавили в предыдущем разделе, мы написали бы –

#/usr/bin/ruby -w

require 'ldap'

$HOST =    'localhost'
$PORT =    LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

conn = LDAP::Conn.new($HOST, $PORT)
conn.bind('cn = root, dc = localhost, dc = localdomain','secret')

conn.perror("bind")
begin
   conn.delete("cn = Zara-Mohtashim, dc = localhost, dc = localdomain")
rescue LDAP::ResultError
   conn.perror("delete")
   exit
end
conn.perror("delete")
conn.unbind

Изменение отличительного имени

Невозможно изменить отличительное имя записи с помощью метода modify . Вместо этого используйте метод modrdn . Вот простой синтаксис метода modrdn

conn.modrdn(dn, new_rdn, delete_old_rdn)

Этот метод изменяет RDN записи с помощью DN, dn , давая ему новое RDN, new_rdn . Если delete_old_rdn имеет значение true , старое значение RDN будет удалено из записи.

пример

Предположим, у нас есть следующая запись –

dn: cn = Zara Ali,dc = localhost,dc = localdomain
cn: Zara Ali
sn: Ali
objectclass: person

Затем мы можем изменить его отличительное имя с помощью следующего кода –

#/usr/bin/ruby -w

require 'ldap'

$HOST =    'localhost'
$PORT =    LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

conn = LDAP::Conn.new($HOST, $PORT)
conn.bind('cn = root, dc = localhost, dc = localdomain','secret')

conn.perror("bind")
begin
   conn.modrdn("cn = Zara Ali, dc = localhost, dc = localdomain", "cn = Zara Mohtashim", true)
rescue LDAP::ResultError
   conn.perror("modrdn")
   exit
end
conn.perror("modrdn")
conn.unbind

Выполнение поиска

Чтобы выполнить поиск в каталоге LDAP, используйте метод поиска с одним из трех различных режимов поиска –

  • LDAP_SCOPE_BASEM – Искать только базовый узел.

  • LDAP_SCOPE_ONELEVEL – Поиск всех дочерних узлов базового узла.

  • LDAP_SCOPE_SUBTREE – Поиск по всему поддереву, включая базовый узел.

LDAP_SCOPE_BASEM – Искать только базовый узел.

LDAP_SCOPE_ONELEVEL – Поиск всех дочерних узлов базового узла.

LDAP_SCOPE_SUBTREE – Поиск по всему поддереву, включая базовый узел.

пример

Здесь мы будем искать все поддерево записи dc = localhost, dc = localdomain для объектов person

#/usr/bin/ruby -w

require 'ldap'

$HOST =    'localhost'
$PORT =    LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

base = 'dc = localhost,dc = localdomain'
scope = LDAP::LDAP_SCOPE_SUBTREE
filter = '(objectclass = person)'
attrs = ['sn', 'cn']

conn = LDAP::Conn.new($HOST, $PORT)
conn.bind('cn = root, dc = localhost, dc = localdomain','secret')

conn.perror("bind")
begin
   conn.search(base, scope, filter, attrs) { |entry|
      # print distinguished name
      p entry.dn
      # print all attribute names
      p entry.attrs
      # print values of attribute 'sn'
      p entry.vals('sn')
      # print entry as Hash
      p entry.to_hash
   }
rescue LDAP::ResultError
   conn.perror("search")
   exit
end
conn.perror("search")
conn.unbind

Это вызывает данный блок кода для каждой соответствующей записи, где запись LDAP представлена ​​экземпляром класса LDAP :: Entry. С последним параметром поиска вы можете указать атрибуты, которые вас интересуют, опуская все остальные. Если вы передадите здесь nil, все атрибуты будут возвращены так же, как «SELECT *» в реляционных базах данных.

Метод dn (псевдоним для get_dn) класса LDAP :: Entry возвращает различающееся имя записи, а с помощью метода to_hash вы можете получить хеш-представление его атрибутов (включая различающееся имя). Чтобы получить список атрибутов записи, используйте метод attrs (псевдоним для get_attributes). Также, чтобы получить список значений одного определенного атрибута, используйте метод vals (псевдоним для get_values).

Обработка ошибок

Ruby / LDAP определяет два разных класса исключений –

  • В случае ошибки методы new, bind или unbind вызывают исключение LDAP :: Error.

  • В случае добавления, изменения, удаления или поиска в каталоге LDAP возникает LDAP :: ResultError.

В случае ошибки методы new, bind или unbind вызывают исключение LDAP :: Error.

В случае добавления, изменения, удаления или поиска в каталоге LDAP возникает LDAP :: ResultError.

Дальнейшее чтение

Для получения полной информации о методах LDAP, пожалуйста, обратитесь к стандартной документации для документации LDAP .

Рубин – Многопоточность

Традиционные программы имеют один поток выполнения: операторы или инструкции, составляющие программу, выполняются последовательно до тех пор, пока программа не завершится.

Многопоточная программа имеет более одного потока выполнения. Внутри каждого потока операторы выполняются последовательно, но сами потоки могут выполняться параллельно, например, на многоядерном процессоре. Часто на одной машине с ЦП несколько потоков фактически не выполняются параллельно, но параллелизм моделируется путем чередования выполнения потоков.

Ruby облегчает написание многопоточных программ с помощью класса Thread . Рубиновые потоки – это легкий и эффективный способ достижения параллелизма в вашем коде.

Создание рубиновых потоков

Чтобы начать новый поток, просто свяжите блок с вызовом Thread.new . Будет создан новый поток для выполнения кода в блоке, а исходный поток немедленно вернется из Thread.new и возобновит выполнение с помощью следующего оператора –

# Thread #1 is running here
Thread.new {
   # Thread #2 runs this code
}
# Thread #1 runs this code

пример

Вот пример, который показывает, как мы можем использовать многопоточную программу Ruby.

#!/usr/bin/ruby

def func1
   i = 0
   while i<=2
      puts "func1 at: #{Time.now}"
      sleep(2)
      i = i+1
   end
end

def func2
   j = 0
   while j<=2
      puts "func2 at: #{Time.now}"
      sleep(1)
      j = j+1
   end
end

puts "Started At #{Time.now}"
t1 = Thread.new{func1()}
t2 = Thread.new{func2()}
t1.join
t2.join
puts "End at #{Time.now}"

Это даст следующий результат –

Started At Wed May 14 08:21:54 -0700 2008
func1 at: Wed May 14 08:21:54 -0700 2008
func2 at: Wed May 14 08:21:54 -0700 2008
func2 at: Wed May 14 08:21:55 -0700 2008
func1 at: Wed May 14 08:21:56 -0700 2008
func2 at: Wed May 14 08:21:56 -0700 2008
func1 at: Wed May 14 08:21:58 -0700 2008
End at Wed May 14 08:22:00 -0700 2008

Жизненный цикл темы

Новые темы создаются с помощью Thread.new . Вы также можете использовать синонимы Thread.start и Thread.fork .

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

Класс Thread определяет ряд методов для запроса и управления потоком во время его работы. Поток запускает код в блоке, связанном с вызовом Thread.new, и затем останавливается.

Значение последнего выражения в этом блоке является значением потока и может быть получено путем вызова метода value объекта Thread. Если поток завершился, то значение сразу возвращает значение потока. В противном случае метод значения блокируется и не возвращается, пока поток не завершится.

Метод класса Thread.current возвращает объект Thread, представляющий текущий поток. Это позволяет потокам манипулировать собой. Метод класса Thread.main возвращает объект Thread, представляющий основной поток. Это начальный поток выполнения, который начался при запуске программы Ruby.

Вы можете дождаться завершения определенного потока, вызвав метод Thread.join этого потока. Вызывающий поток будет блокироваться, пока данный поток не будет завершен.

Потоки и исключения

Если исключение возникает в главном потоке и нигде не обрабатывается, интерпретатор Ruby печатает сообщение и завершает работу. В потоках, отличных от основного потока, необработанные исключения приводят к прекращению работы потока.

Если поток t завершается из-за необработанного исключения, а другой поток s вызывает t.join или t.value, то исключение, возникшее в t, вызывается в потоке s .

Если Thread.abort_on_exception имеет значение false , условие по умолчанию, необработанное исключение просто убивает текущий поток, а все остальные продолжают работать.

Если вы хотите, чтобы любое необработанное исключение в каком-либо потоке вызывало выход интерпретатора, установите для метода класса Thread.abort_on_exception значение true .

t = Thread.new { ... }
t.abort_on_exception = true

Переменные потока

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

Класс потока имеет специальную возможность, позволяющую создавать локальные переменные потока и обращаться к ним по имени. Вы просто обрабатываете объект потока, как если бы это был Hash, записывая в элементы с помощью [] = и читая их обратно с помощью [].

В этом примере каждый поток записывает текущее значение счетчика переменных в локальную переменную с ключом mycount .

Live Demo

#!/usr/bin/ruby

count = 0
arr = []

10.times do |i|
   arr[i] = Thread.new {
      sleep(rand(0)/10.0)
      Thread.current["mycount"] = count
      count += 1
   }
end

arr.each {|t| t.join; print t["mycount"], ", " }
puts "count = #{count}"

Это дает следующий результат –

8, 0, 3, 7, 2, 1, 6, 5, 4, 9, count = 10

Основной поток ожидает завершения подпотоков, а затем выводит значение счетчика, захваченного каждым.

Приоритеты потоков

Первым фактором, влияющим на планирование потоков, является приоритет потоков: потоки с высоким приоритетом планируются перед потоками с низким приоритетом. Точнее, поток получит процессорное время, только если нет потоков с более высоким приоритетом, ожидающих запуска.

Вы можете установить и запросить приоритет объекта Ruby Thread с приоритетом = и приоритетом . Вновь созданный поток начинается с того же приоритета, что и поток, который его создал. Основной поток начинается с приоритета 0.

Нет никакого способа установить приоритет потока прежде, чем он начнет работать. Тем не менее, поток может повысить или понизить свой собственный приоритет как первое действие, которое он предпринимает.

Исключение потоков

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

Mutex – это класс, который реализует простую семафорную блокировку для взаимоисключающего доступа к некоторому общему ресурсу. То есть только один поток может удерживать блокировку в данный момент времени. Другие потоки могут ожидать очереди, чтобы блокировка стала доступной, или просто получать немедленную ошибку, указывающую, что блокировка недоступна.

Размещая все доступы к совместно используемым данным под контролем мьютекса , мы гарантируем согласованность и атомарную работу. Давайте попробуем привести примеры, первый без мутатакса, а второй с мутаксом –

Пример без Mutax

Live Demo

#!/usr/bin/ruby
require 'thread'

count1 = count2 = 0
difference = 0
counter = Thread.new do
   loop do
      count1 += 1
      count2 += 1
   end
end
spy = Thread.new do
   loop do
      difference += (count1 - count2).abs
   end
end
sleep 1
puts "count1 :  #{count1}"
puts "count2 :  #{count2}"
puts "difference : #{difference}"

Это даст следующий результат –

count1 :  1583766
count2 :  1583766
difference : 0

Live Demo

#!/usr/bin/ruby
require 'thread'
mutex = Mutex.new

count1 = count2 = 0
difference = 0
counter = Thread.new do
   loop do
      mutex.synchronize do
         count1 += 1
         count2 += 1
      end
   end
end
spy = Thread.new do
   loop do
      mutex.synchronize do
         difference += (count1 - count2).abs
      end
   end
end
sleep 1
mutex.lock
puts "count1 :  #{count1}"
puts "count2 :  #{count2}"
puts "difference : #{difference}"

Это даст следующий результат –

count1 :  696591
count2 :  696591
difference : 0

Обработка тупика

Когда мы начинаем использовать объекты Mutex для исключения потоков, мы должны быть осторожны, чтобы избежать тупиков . Deadlock – это состояние, которое возникает, когда все потоки ожидают получения ресурса, удерживаемого другим потоком. Поскольку все потоки заблокированы, они не могут снять блокировки, которые они удерживают. И поскольку они не могут снять блокировки, никакой другой поток не может получить эти блокировки.

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

пример

Live Demo

#!/usr/bin/ruby
require 'thread'
mutex = Mutex.new

cv = ConditionVariable.new
a = Thread.new {
   mutex.synchronize {
      puts "A: I have critical section, but will wait for cv"
      cv.wait(mutex)
      puts "A: I have critical section again! I rule!"
   }
}

puts "(Later, back at the ranch...)"

b = Thread.new {
   mutex.synchronize {
      puts "B: Now I am critical, but am done with cv"
      cv.signal
      puts "B: I am still critical, finishing up"
   }
}
a.join
b.join

Это даст следующий результат –

A: I have critical section, but will wait for cv
(Later, back at the ranch...)
B: Now I am critical, but am done with cv
B: I am still critical, finishing up
A: I have critical section again! I rule!

Состояния потоков

Существует пять возможных возвращаемых значений, соответствующих пяти возможным состояниям, как показано в следующей таблице. Метод status возвращает состояние потока.

Состояние потока Возвращаемое значение
Runnable бежать
Спать Спать
Aborting отбрасывание
Завершается нормально ложный
Прекращено за исключением ноль

Методы класса потока

Следующие методы предоставляются классом Thread, и они применимы ко всем потокам, доступным в программе. Эти методы будут вызываться как использующие имя класса Thread следующим образом:

Thread.abort_on_exception = true

Thread.abort_on_exception

Возвращает статус глобального прерывания при условии исключения . По умолчанию установлено значение false . При значении true все потоки будут прерваны (процесс завершит работу (0)), если в каком-либо потоке возникнет исключение

Thread.abort_on_exception =

Если установлено значение true , все потоки будут прерваны, если возникнет исключение. Возвращает новое состояние.

Thread.critical

Возвращает состояние критического состояния глобального потока .

Thread.critical =

Устанавливает состояние критического состояния глобального потока и возвращает его. При значении true запрещает планирование любого существующего потока. Не блокирует создание и запуск новых потоков. Некоторые операции с потоками (такие как остановка или уничтожение потока, переход в спящий режим в текущем потоке и создание исключения) могут привести к планированию потока даже в критической секции.

Thread.current

Возвращает текущий исполняемый поток.

Thread.exit

Завершает текущий запущенный поток и планирует запуск другого потока. Если этот поток уже помечен для уничтожения, exit возвращает поток . Если это основной поток или последний поток, выйдите из процесса.

Thread.fork {блок}

Синоним для Thread.new.

Thread.kill (aThread)

Заставляет данную нить выйти

Thread.list

Возвращает массив объектов Thread для всех потоков, которые могут быть запущены или остановлены. Нить.

Thread.main

Возвращает основной поток для процесса.

Thread.new ([arg] *) {| арги | блок}

Создает новый поток для выполнения инструкций, указанных в блоке, и начинает его выполнение. Все аргументы, переданные в Thread.new , передаются в блок.

Thread.pass

Вызывает планировщик потока, чтобы передать выполнение другому потоку.

Thread.start ([аргументы] *) {| арги | блок}

В основном так же, как Thread.new . Однако, если класс Thread является подклассом, то вызов start в этом подклассе не вызовет метод инициализации подкласса.

Thread.stop

Останавливает выполнение текущего потока, переводит его в состояние сна и планирует выполнение другого потока. Сбрасывает критическое состояние на ложное.

Методы экземпляра потока

Эти методы применимы к экземпляру потока. Эти методы будут вызываться как использующие экземпляр Thread следующим образом:

#!/usr/bin/ruby

thr = Thread.new do   # Calling a class method new
   puts "In second thread"
   raise "Raise exception"
end
thr.join   # Calling an instance method join

ч [символ]

Ссылка на атрибут – возвращает значение локальной переменной потока, используя символ или имя aSymbol . Если указанная переменная не существует, возвращает nil .

thr [aSymbol] =

Назначение атрибута – Устанавливает или создает значение локальной переменной потока, используя символ или строку.

thr.abort_on_exception

Возвращает статус прерывания при условии исключения для thr . По умолчанию установлено значение false .

thr.abort_on_exception =

При значении true все потоки (включая основную программу) отменяются, если в thr вызывается исключение. Процесс будет эффективно завершен (0) .

thr.alive?

Возвращает true, если thr работает или спит.

thr.exit

Завершает работу thr и планирует запуск другого потока. Если этот поток уже помечен для уничтожения, exit возвращает поток. Если это основной поток или последний поток, выход из процесса.

thr.join

Вызывающий поток приостановит выполнение и запустит thr . Не возвращается, пока не выйдет. Любые не присоединенные потоки будут уничтожены при выходе из основной программы.

thr.key?

Возвращает true, если данная строка (или символ) существует как локальная переменная потока.

thr.kill

Синоним для Thread.exit .

thr.priority

Возвращает приоритет thr . По умолчанию ноль; потоки с более высоким приоритетом будут работать до потоков с более низким приоритетом.

thr.priority =

Устанавливает приоритет thr в Integer. Потоки с более высоким приоритетом будут работать до потоков с более низким приоритетом.

thr.raise (исключение)

Возникает исключение из тр . Звонящий не должен быть тр .

thr.run

Просыпается , делая его подходящим для планирования. Если не в критическом разделе, то вызывает планировщик.

thr.safe_level

Возвращает действующий безопасный уровень для thr .

thr.status

Возвращает состояние thr : sleep, если thr спит или ожидает ввода-вывода, запускается, если выполняется thr , false, если thr завершается нормально, и nil, если thr завершается с исключением.

thr.stop?

Возвращает true, если thr мертв или спит.

thr.value

Ожидает завершения thr через Thread.join и возвращает его значение.

thr.wakeup

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

Ruby – встроенные функции

Поскольку модуль Kernel включен в класс Object , его методы доступны везде в программе Ruby. Они могут быть вызваны без получателя (функциональная форма). Поэтому их часто называют функциями.

выкинуть

Завершает программу. Если возникает исключение (т. Е. $! Not nil), отображается его сообщение об ошибке.

Array (объект)

Возвращает obj после преобразования его в массив, используя to_ary или to_a.

at_exit {…}

Регистрирует блок для выполнения при выходе из программы. Аналогичен оператору END, но оператор END регистрирует блок только один раз.

автозагрузка (имя класса, файл)

Регистрирует имя класса класса для загрузки из файла при первом использовании. имя класса может быть строкой или символом.

переплет

Возвращает текущую переменную и привязки метода. Возвращаемый объект Binding может быть передан методу eval в качестве второго аргумента.

block_given?

Возвращает true, если метод был вызван с блоком .

callcc {| с | …}

Передает объект продолжения c в блок и выполняет блок. callcc может использоваться для глобального выхода или конструкции цикла.

звонящий ([n])

Возвращает текущий стек выполнения в массиве строк в файле формы : строка . Если указано n, возвращает записи стека с n-го уровня вниз.

поймать (тег) {…}

Ловит нелокальный выход броском, вызванным во время выполнения его блока.

chomp ([rs = $ /])

Возвращает значение переменной $ _ с удаленным завершающим символом новой строки, присваивая результат обратно $ _. Значение строки новой строки можно указать с помощью rs.

chomp! ([rs = $ /])

Удаляет символ новой строки из $ _, изменяя строку на месте.

нарубить

Возвращает значение $ _ с последним удаленным последним символом (один байт), присваивая результат обратно $ _.

рубить!

Удаляет последний символ из $ _, изменяя строку на месте.

eval (str [, scope [, file, line]])

Выполняет str как код Ruby. Привязка для выполнения оценки может быть указана с областью действия . Имя файла и номер строки кода, подлежащего компиляции, могут быть указаны с использованием файла и строки.

exec (cmd [, arg …])

Заменяет текущий процесс, выполнив команду cmd . Если указано несколько аргументов, команда выполняется без расширения оболочки.

выход ([результат = 0])

Выход из программы с результатом в качестве возвращенного кода состояния.

выход! ([результат = 0])

Убивает программу в обход обработки выхода, такой как обеспечение и т. Д.

потерпеть поражение(…)

Смотрите поднять (…)

Float (объект)

Возвращает obj после преобразования его в число с плавающей точкой. Числовые объекты конвертируются напрямую; ноль преобразуется в 0,0; строки конвертируются с учетом префикса 0x, 0b radix. Остальные конвертируются с использованием obj.to_f.

вилка

fork {…}

Создает дочерний процесс. nil возвращается в дочернем процессе, а ID дочернего процесса (целое число) возвращается в родительском процессе. Если указан блок, он запускается в дочернем процессе.

формат (fmt [, arg …])

Смотрите спринтф.

получает ([rs = $ /])

Считывает имя файла, указанное в командной строке или одну строку из стандартного ввода. Строка разделителя записей может быть указана явно с помощью rs.

global_variables

Возвращает массив имен глобальных переменных.

gsub (x, y)

gsub (x) {…}

Заменяет все строки, соответствующие x в $ _, на y. Если указан блок, совпадающие строки заменяются результатом блока. Измененный результат присваивается $ _.

gsub! (x, y)

gsub! (x) {…}

Выполняет ту же замену, что и gsub, за исключением того, что строка изменяется на месте.

Целое число (объект)

Возвращает obj после преобразования его в целое число. Числовые объекты конвертируются напрямую; ноль преобразуется в 0; строки конвертируются с учетом префикса 0x, 0b radix. Остальные конвертируются с использованием obj.to_i.

лямбда {| х | …}

proc {| х | …}

лямбда

процедура

Преобразует блок в объект Proc . Если блок не указан, блок, связанный с вызывающим методом, преобразуется.

загрузить (file [, private = false])

Загружает Ruby-программу из файла . В отличие от require , он не загружает библиотеки расширений. Если для private установлено значение true , программа загружается в анонимный модуль, тем самым защищая пространство имен вызывающей программы.

local_variables

Возвращает массив имен локальных переменных.

цикл {…}

Повторяет блок кода.

open (путь [, mode = “r”])

open (путь [, mode = “r”]) {| е | …}

Открывает файл . Если указан блок, блок выполняется с открытым потоком, переданным в качестве аргумента. Файл закрывается автоматически при выходе из блока. Если путь начинается с канала |, следующая команда запускается как команда, и возвращается поток, связанный с этим процессом.

р (объект)

Отображает obj, используя метод inspect (часто используется для отладки).

печать ([arg …])

Печатает arg в $ defout . Если аргументы не указаны, выводится значение $ _.

printf (fmt [, arg …])

Форматирует arg в соответствии с fmt, используя sprintf, и выводит результат в $ defout . Для получения более подробной информации о форматировании см. Sprintf.

proc {| х | …}

процедура

Смотри лямду.

putc (c)

Выводит один символ на вывод по умолчанию ( $ defout ).

ставит ([стр])

Выводит строку на вывод по умолчанию ( $ defout ). Если строка не заканчивается новой строкой, новая строка добавляется к строке.

поднять (…)

потерпеть поражение(…)

Возникает исключение. Предполагает RuntimeError, если класс исключений не указан. Вызов рейса без аргументов в предложении спасения повторно вызывает исключение. Если сделать это вне условия восстановления, возникает RuntimeError без сообщений . fail – устаревшее имя для рейза.

ранд ([макс = 0])

Генерирует псевдослучайное число, большее или равное 0 и меньшее, чем макс. Если max либо не указано, либо установлено в 0, случайное число возвращается как число с плавающей запятой, большее или равное 0 и меньшее 1. srand может использоваться для инициализации псевдослучайного потока.

readline ([rs = $ /])

Эквивалент get, за исключением того, что он вызывает исключение EOFError при чтении EOF.

читать строки ([rs = $ /])

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

требовать (lib)

Загружает библиотеку (включая библиотеки расширений) lib при первом ее вызове. require не будет загружать одну и ту же библиотеку более одного раза. Если расширение не указано в lib , require пытается добавить к нему .rb, .so и т. Д.

сканирование (пере)

scan (re) {| x | …}

Эквивалент $ _. Scan.

выберите (читает [, пишет = ноль [, исключает = ноль [, время ожидания = ноль]]])

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

set_trace_func (proc)

Устанавливает обработчик для трассировки. proc может быть строкой или объектом proc . set_trace_func используется отладчиком и профилировщиком.

сон ([сек])

Приостанавливает выполнение программы на секунды. Если sec не указан, программа приостанавливается навсегда.

разделить ([sep [, max]])

Эквивалент $ _. Split.

sprintf (fmt [, arg …])

формат (fmt [, arg …])

Возвращает строку, в которой arg отформатирован в соответствии с fmt. Спецификации форматирования в основном такие же, как и для sprintf в языке программирования C. Спецификаторы преобразования (% с последующим указателем поля преобразования) в fmt заменяются форматированной строкой соответствующего аргумента. Список поданных конверсий приведен ниже в следующем разделе.

сранд ([семя])

Инициализирует массив случайных чисел. Если seed не указан, инициализация выполняется с использованием времени и другой системной информации для seed.

Строка (объект)

Возвращает obj после преобразования его в строку, используя obj.to_s.

системный вызов (sys [, arg …])

Вызывает функцию вызова операционной системы, указанную номером sys . Числа и значение sys зависят от системы.

система (cmd [, arg …])

Выполняет cmd как вызов командной строки. Если указано несколько аргументов, команда запускается напрямую без расширения оболочки. Возвращает true, если возвращаемый статус равен 0 (успех).

sub (x, y)

sub (x) {…}

Заменяет первую строку, соответствующую x в $ _, на y. Если указан блок, совпадающие строки заменяются результатом блока. Измененный результат присваивается $ _.

sub! (x, y)

sub! (x) {…}

Выполняет ту же замену, что и sub, за исключением того, что строка изменяется на месте.

тест (тест, f1 [, f2])

Выполняет различные файловые тесты, указанные символьным тестом . Чтобы улучшить читабельность, вы должны использовать методы класса File (например, File :: readable?), А не эту функцию. Список аргументов приведен ниже в следующем разделе.

бросить (тег [, значение = ноль])

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

trace_var (var, cmd)

trace_var (var) {…}

Устанавливает трассировку для глобальной переменной. Имя переменной указывается в виде символа. cmd может быть строкой или объектом Proc.

ловушка (сиг, смд)

ловушка (сиг) {…}

Устанавливает обработчик сигнала. sig может быть строкой (например, SIGUSR1) или целым числом. SIG может быть опущен в имени сигнала. Обработчик сигнала для сигнала EXIT или сигнала номер 0 вызывается непосредственно перед завершением процесса.

untrace_var (var [, cmd])

Удаляет трассировку для глобальной переменной. Если указан cmd , удаляется только эта команда.

Функции для чисел

Вот список встроенных функций, связанных с числом. Их следует использовать следующим образом –