Детский садик - Форум
Добро пожаловать на наш форум! ;) Мы рады Вас видеть! Войдите или зарегистрируйтесь. Регистрация дает вам больше преимуществ, вы можете воспользоваться функциями, которые не доступны гостям... а также оставить свое драгоценное мнение!
Детский садик - Форум
Добро пожаловать на наш форум! ;) Мы рады Вас видеть! Войдите или зарегистрируйтесь. Регистрация дает вам больше преимуществ, вы можете воспользоваться функциями, которые не доступны гостям... а также оставить свое драгоценное мнение!
Детский садик - Форум
Вы хотите отреагировать на этот пост ? Создайте аккаунт всего в несколько кликов или войдите на форум.



 
ФорумПоследние изображенияРегистрацияВход

Здравствуйте Гость, сегодня Пт 19 Апр 2024, 17:28.

Информер праздники сегодня Праздники России
Юмор bash.org.ru
Анекдоты

Поделиться | 
 

 Осваиваем Ruby

Предыдущая тема Следующая тема Перейти вниз 
АвторСообщение
3EH
Модератор
Модератор
3EH


Профиль
СообщениеТема: Осваиваем Ruby   Осваиваем Ruby EmptyВс 03 Апр 2011, 21:05

Всё же есть огромное желание перестать вообще думать о делфях и перейти к более современным, часто используемым и кроссплатформенным языкам... Очевидно, в идеале это java, C/C++, php. Но сразу прям взяться и изучать с нуля какой либо из них, думаю, крайне тяжело. Своеобразным перевалочным моментом будет ruby. Да и поговаривают, пхп он не уступает и фреймворк свой даже есть.
Понятия не имею зачем пишу этот пост, в любом случаю самому нужно будет по ходу изучения нового материала делать записи, а то потом заброшу на некоторое время, забуду всё и не вернусь к дальнейшему изучению, а тут всё в одном месте будет, да и потом пдф-ку сваять можно. Ну и может кто со мной согласиться повыносить мозг поизучать. (сомневаюсь)
ps: да, да, что только не сделаешь, чтобы не писать диплом...
pps: тему закрою, обсуждение здесь: [Вы должны быть зарегистрированы и подключены, чтобы видеть эту ссылку]


Последний раз редактировалось: 3EH (Вс 03 Апр 2011, 21:43), всего редактировалось 2 раз(а)
Вернуться к началу Перейти вниз
3EH
Модератор
Модератор
3EH


Профиль
СообщениеТема: Re: Осваиваем Ruby   Осваиваем Ruby EmptyВс 03 Апр 2011, 21:24

Для начала узнаем что это, зачем это и почему это

Что такое Ruby?
Руби — это полноценный интерпретируемый язык программирования высокого уровня для объектно-ориентированного программирования. Интерпретируемый — значит что код программы хранится в виде обычного текста, который передается исполняющему его интерпретатору. Можно сравнить с PHP и C++ — как и в PHP достаточно написать код, условно загрузить его на сервер-хостинг, где его будет выполнять интерпретатор. В противовес C++ необходимо компилировать, но зато мы получаем готовое приложение, которое выполняется само по себе, никуда код передавать не надо, но и посмотреть в исходники, заглянуть в программу, увы, не выйдет — там нечитаемый бинарный код. Возвращаясь к Руби, делаем вывод, что язык этот замечателен для разработки веб-приложений, скриптов, в ОС же его использование ограничено скоростью приложения (для фронтендов и небольших утилит Ruby очень даже подходит).

Что такое Ruby on Rails?
Дословно: «Руби на Рельсах». На какие такие рельсы поставили этот ЯП? Rails — это наиболее известный фрэймворк для языка Ruby. Мы можем писать скрипты и на «чистом» Ruby (подобно большинству скриптов на PHP), однако рельсы позволяют повысить скорость, производительность написания кода, кроме того, этот фрэймворк реализует архитектуру MVC (Model — View — Controller) — о том, что это такое и как это использовать, поговорим позже.

Концепции Ruby и Rails
Ruby и Ruby on Rails следуют паре принципов для того, чтобы помочь писать код чище и красивее. Первый: DRY (Don't repeat yourself). Это означает, что мы должны писать необходимый код только один раз и только в строго определенном месте. Второй: CoC (Conventions over Configuration) — общие соглашения важнее собственной конфигурации. Для большинства необходимых в кодинге методов уже есть замечательные автоматические установки, которые и следует использовать, а в крайних случаях, если умолчания нас не устраивают, мы просто переписываем их под себя. Всё, для того, чтобы код был чистым и лаконичным, и при этом мы затрачивали минимум усилий.

Почему Ruby?
  • Язык предельно лёгок в изучении в сравнении с другими ЯП
  • Полностью объектно-ориентированный
  • Архитектура MVC у Rails
  • Нет необходимости писать много кода
  • Очень расширяемый
  • Open Source
  • Несмотря на то, что фрэймворк Rails молодой, он многофункционален и содержит совсем немного багов


Что нам понадобиться
  • сам интерпретатор Ruby
  • фрэймворк Rails, база данных (MySQL, думаю, будет лучшим выбором)
  • непосредственно среда разработки, которая должна сделать процесс программирования приятным, удобным и увлекательным ;)


Среда для разработки
Как и в других интерпретируемых языках создавать готовые программы можно и в Блокноте, однако же мы всерьёз схватились за Руби ;) Стоило бы, наверное, погуглить IDE для языка, провести какое-то тестирования производительности и функциональности. Но мы же непрофессионалы, так что ищем наиболее универсальное, надежное, качественное, проверенное решение. И оно есть: это [Вы должны быть зарегистрированы и подключены, чтобы видеть эту ссылку] для Microsoft Visual Studio 2005/2008. Да, это сугубо коммерческий, закрытый продукт только для Windows. Но, во-первых, это знакомая IDE, которая верно будет вам служить в будущем, во-вторых она не базируется на Java, что положительно отражается на скорости работы, в-третьих, полнофункциональная trial-версия работает 60 дней, чего, я надеюсь, нам будет достаточно для нашего курса.
Если же вы отдаете предпочтение другим ОС, то несомненно стоит взглянуть на свободный кроссплатформенный [Вы должны быть зарегистрированы и подключены, чтобы видеть эту ссылку].
Выбранная вами среда разработки в дальнейшем особого значения не имеет, однако процесс установки компонентов я буду освещать всё таки для Ruby in Steel (хотя в дальнейшем вернусь на nix-систему, но пока как то больше времени приходится под виндой проводить) — он достаточно прост, так как вы можете скачать All-in-One Installer — готовый пакет с бесплатным Visual Studio 2008 и всем необходимым для нашего учебного места (ищем на торрентах или обращаемся ко мне ;)).
После начала установки, отметьте нужные пакеты (в большинстве случаев стоит оставить все по умолчанию), нажмите Install и только успевайте нажимать Next и Finish в появляющихся окнах установщиков. В процессе установки будут загружены и установлены последние Rails, поэтому консольные окна не закрываем и ждем, когда появится «Press any key to continue...». Для MySQL можем задать запуск в виде сервиса Windows и установить пароль рута.
Никакой дополнительной конфигурации не требуется — просто запускаем свежеустановленный Visual Studio.

Дополнение: NetBeans IDE есть и под windows, причем он бесплатен и, по моему скромному мнению, получше будет чем Visual Studio
скачать можно по этой ссылке: [Вы должны быть зарегистрированы и подключены, чтобы видеть эту ссылку]


Последний раз редактировалось: 3EH (Ср 06 Апр 2011, 20:04), всего редактировалось 1 раз(а)
Вернуться к началу Перейти вниз
3EH
Модератор
Модератор
3EH


Профиль
СообщениеТема: Re: Осваиваем Ruby   Осваиваем Ruby EmptyПн 04 Апр 2011, 19:06

Первый проект
Проект в Ruby in Steel создаем как обычно в VS: File — New — Project — Ruby In Steel (слева) — Iron Ruby.... (справа).
Стоит уделить внимание иерархии организации работы с кодом — проект (Project) содержит в себе один или несколько файлов в одной или нескольких папках, в то же время Solution (решение) может содержать несколько проектов.
После создания проекта он уже содержит в себе один пустой файл rubyfile.rb, новые файлы добавляются через контекстное меню проекта. Двойной щелчок по имени файла открывает его в редакторе. Дальнейший код будем писать прямо в rubyfile.rb — это наш тестовый файл.

Первая программа
Традиционно это Hello World:
Код:
puts "Hello World!"
Упс, это всё… Ctrl+F5 в среде — и результат, так сказать, налицо!

Игры со строками
Код:
puts "Hello World!\nPrivet Mir!"
Как вы заметили прямо в строках работают управляющие последовательности (Escape Sequences), в т.ч. \n (новая строка), \t (табуляция), \s (пробел) и др.
Код:
puts 'Hello World!\nPrivet Mir!'
А вот строка, заключенная в апострофы «глупая» — она не понимает ES, поэтому в большинстве случаев используем именно кавычки. Однако если заранее известно, что ES в строке не нужны, то апострофы позволяют выиграть в производительности приложения.
Код:
puts 'It\'s Ruby'
Хотя нет, «глупая» строка понимает \' и больше ничего.
Код:
print "Hello World!"
print "Hello World!"
В отличие от оператора puts print не делает перенос строки после вывода переменной.
Код:
puts "2 x 2 = #{2*2}"
Замечательная возможность Ruby — регулярное выражение в переменной — вы можете вставлять кусочки кода Ruby прямо в строки используя конструкцию #{code}.
Код:
puts "#{"Ruby! "*4}"
«Умножаем» строку на четыре и получаем слова песни Kaiser Chiefs ;) Причем делаем все это в одной строке кода!


Последний раз редактировалось: 3EH (Пн 04 Апр 2011, 19:26), всего редактировалось 1 раз(а)
Вернуться к началу Перейти вниз
3EH
Модератор
Модератор
3EH


Профиль
СообщениеТема: Re: Осваиваем Ruby   Осваиваем Ruby EmptyПн 04 Апр 2011, 19:25

Числа и Выражения
В программировании выражением (expression) называется комбинация чисел, операторов и переменных, которая, будучи понята компьютером, дает результат в какой-либо форме. Вот несколько примеров:
Цитата :
8
2 + 3
"a" + "b" + "c"
100 - 5 * (2 - 1)
x + y
Рассмотрим и разберем простой код:
Код:
x = 5
y = x * 20
x += y
puts x
Придаём переменной x значение 5, для y устанавливаем значение x * 20 (100). Затем прибавляем y к x и выводим результат. Все передельно ясно, единственная заминка может возникнуть на третьей строке. Казалось бы адекватнее написать x = x + y, однако это — кусочек сахара Ruby. Также можем использовать x *= y и x /=, а x += 1 увеличит переменную на единицу.

Операторы сравнения и условия
Код:
age = 22
puts "Sovsem Molodoi!" if age < 25
Компьютер не только выполняет заданные операции (иначе это был бы просто калькулятор), он использует логику для определения направления работы. Результат исполнения кода предсказуем. Разберем вторую строку. Прежде всего обратим внимание на age < 25 — известные всем «больше/меньше» (а также ==, >=, <=, <=>, !=) работают и в Руби. Дальше видим знакомое из других языков условие: if. А где же then, end? Еще один сахарок Руби, на самом деле вторая строка полностью аналогична коду:
Код:
if age < 25 then
puts "Sovsem Molodoi!"
end
Условия можно комбинировать. Чтобы получить противоположный эффект можно использовать слово unless:
Код:
age = 24
puts "You're NOT a teenager" unless age > 12 && age < 20
Код понятен. Идем дальше.

Итераторы
Вот что ожидает нас здесь:
Код:
4.times do puts "Ruby" end
Давайте попробуем запустить код — результатом будет четырёхкратное выполнение puts. Анализируем. В первую очередь берётся число 4, затем для него вызывается метод times, применимый ко всем числам в Руби (метод? что такое метод? это действие — об этом поговорим позже). Вместо того, чтобы передавать в метод данные, мы передаём ему код, находящийся между do и end. Метод times затем 4 раза выполняет этот самый код. Как всегда Руби хочет, чтобы нам было удобнее писать программки, и поэтому дает еще одно послабление. Полностью аналогичный код, без do и end:
Код:
4.times { puts "Ruby" }
В Руби (да и в других ЯП тоже) одним из механизмов создания циклов является итератор — это некий объект, который позволяет перебирать все элементы какого-либо набора. В нашем случае он задает цикл, или итерирует, в четыре повтора. Посмотрим другие итераторы, применимые к числам в Руби:
Код:
1.upto(5) { ...код цикла... }
10.downto(5) { ...код цикла... }
0.step(50, 5) { ...код цикла... }
Думаю, назначение каждого из них понятно. Снова код:
Код:
1.upto(5) { |number| puts number }
В результате программа «посчитает до пяти» — мы передали состояние итерации в код. В начале циклируемого кода число «от 1 до 5» отправляется в переменную number.

Плавающая точка
Наверняка вы заметили, что во всех написанных ранее программах нам не приходилось объявлять переменные, определять их тип — Руби делает это за нас (продолжаем лизать сахар). Попробуем разделить:
Код:
puts 10 / 3
Результат — 3. Так как входящие числа целые, то и результат остался целым. Руби хотел помочь, но у него не получилось. Давайте подскажем ему:
Код:
puts 10.0 / 3.0
Решение оказалось простым!
Иногда мы оказываемся в такой ситуации, что не можем контролировать входящие числа, однако и тут есть решение:
Код:
x = 10
y = 3
puts x.to_f / y.to_f
Для целых чисел есть специальный метод (т.е. действие) .to_f, преобразующий их в числа с плавающей точкой на лету. Обратное действие (округление до целой части) выполняет метод .to_i.


Последний раз редактировалось: 3EH (Вт 05 Апр 2011, 17:42), всего редактировалось 1 раз(а)
Вернуться к началу Перейти вниз
3EH
Модератор
Модератор
3EH


Профиль
СообщениеТема: Re: Осваиваем Ruby   Осваиваем Ruby EmptyВт 05 Апр 2011, 17:35

Немного об ООП
Нам пока удавалось уходить от ООП. На самом деле — в Руби всё, с чем мы манипулируем — это объекты. ВСЁ! Это отличает язык от C++ и Java, где присутствуют примитивные типы и фразы, не возвращающие значения. При написании кода на Ruby, как и любого другого ОО кода, мы прежде всего создаем модели, а не пытаемся повторить весь процесс в коде. Например, если вам нужно написать приложение для кулинарной книги, вы, скорее всего, захотите создать список рецептов. Для моделирования вам придется использовать некоторые способы сортировки, чтобы воспроизводить различные виды данных, синхронизировать позиции необходимых данных в каждом списке и др. нонсенс. ООП делает работу легче, предлагая вам создавать классы и объекты, чтобы моделировать необходимые составляющие. В нашем примере вы можете создать класс Рецепты со строчными атрибутами название и автор и атрибутом в виде массива ингридиенты. Назначение класса — моделировать какую-либо вещь в вашей программе. Класс — это прототип, чертёж «существительных» в вашем проекте: объектов. Экземпляры класса или объекты (взаимозаменяемые термины) затем берут эти прототипы и запускают их в действие. В примере объекты могут быть созданы для каждого рецепта в списке, которые будут экземплярами класса Рецепты, который в свою очередь будет содержать данные и делать вещи, относящиеся к рецептам (например, держать список ингридиентов, добавлять ингридиенты в этот список, и т. п.) и следить за целостностью рецептов (например, что только числа в количествах ингридиентов, что каждый рецепт должен иметь название и др.) — все эти действия над объектами, «глаголы», и есть методы.
Да, действительно, любое число — также полноценный объект. В примере 4.times {puts "Ruby"} число 4 — объект, является экземпляром класса Integer (мы об этом не заявляем в коде, Руби делает это за нас), к нему применяется метод times, который прописан в классе (опять мы этого не видим, но это подразумевается). Более того, даже в выражении x = 1 + x единица — это объект, а + — его метод! Вот так, не зная принципов ООП, мы уже, сами того не заметив, стали «жертвами» объектно-ориентированного программирования smile

Классы, объекты, методы
Вместо того, чтобы углубляться дальше в синтаксис Ruby, отставим циклы, типы, модули и др. — мы вернёмся к ним позже. Сейчас же мы посмотрим, как создавать классы, объекты и методы.
Как и в других объектных языках объекты определяются классом. Например этот класс определяет собак (о_0):
Код:
class Dog
  def set_name( aName )
    @myname = aName
  end
end
Ну а чем вам собаки — не класс? ;) Смотрим код. Определение класса начинается с ключевого слова class и названия самого класса, которое обязано должно начинаться с большой буквы. В классе определен метод set_name (def...end), который будет называть каждый объект-собаку. Он берёт входящий аргумент aName и назначает его значение переменной @myname.
Переменные, начинающиеся с @, — это переменные экземпляра класса. Важно то, что значение такой переменной доступно только внутри экземпляра, к которому она принадлежит. Создадим два объекта (две конкретные собаки) с помощью метода new:
Код:
moya = Dog.new
tvoya = Dog.new
Напоминаю и запоминаем: класс называем только с большой буквы, объект — только со строчной. Используем метод set_name, чтобы назвать собак:
Код:
moya.set_name( 'Lassie' )
tvoya.set_name( 'Rex' )
Как теперь вывести клички собак? Мы не можем «вытащить» переменную @name из объекта, так как внутренние данные объекта известны только ему (см. выше). Это основной принцип ООП: данные объекта приватны; это называется скрытие данных и является частью принципа инкапсуляции.
Для решения этой задачки просто добавим новый метод в класс, который будет выводить переменную:
Код:
def get_name
  return @myname
end
Слово return необзательно, Руби возвратит последнее полученное значение, однако писать его — хорошая привычка.
Заставим собаку лаять (для этого напишем еще один метод) и соберём всё в кучу:
Код:
class Dog   
  def set_name( aName )
    @myname = aName
  end
 
  def get_name
    return @myname
  end
 
  def gav
    return 'r-r-r-r!'
  end
end

dog1 = Dog.new
dog1.set_name( 'Fido' )
puts(dog1.get_name)
puts(dog1.gav)
Представим, что у нас есть два класса (например, кошки и собаки), в каждом определено по объекту (конкретные кот и пёс) и методу с одинаковыми названиями («говорить», но кот мяукает, а пёс лает). Получается, что на один и тот же метод объекты реагируют по-разному. Возможность иметь несколько классов, содержащих одноименные методы, называется полиморфизм. Узнали… и забыли это грозное слово.

Атрибуты
Для нашей задачи есть другой подход — создадим необходимые методы с помощью атрибутов класса. Усложним поставленное задание и создадим зоопарк ;)
Код:
class Cat
  attr_accessor :name, :age, :gender, :color
end
class Dog
  attr_accessor :name, :age, :gender, :color
end
class Snake
  attr_accessor :name, :age, :gender, :color, :length
end
Рассмотрим вторую строку. Она предоставляет три атрибута для класса Cat. Каждая кошка имеет свою кличку, возраст, пол и окрас — и код создает эти атрибуты. _accessor означает «сделайте эти атрибуты доступными для создания и изменения».
Создадим объект и применим атрибуты:
Код:
cat_object = Cat.new
cat_object.name = "Pussy"
........................
puts cat_object.name

Наследование
Посмотрев на последний код с объявлением трёх классов, легко заметить, что они предельно похожи. Лишь у змеи дополнительно определена длина. Вспомним принципы программирования на Ruby. Один из них: DRY (Don't repeat yourself), который означает, что мы должны писать необходимый код только один раз, а у нас сплошные повторения. Нам просто необходимо обратить внимание на одну из лучших возможностей ООП: наследование.
Наследование позволяет разным классам соотноситься друг с другом и группироваться по схожестям в структуре. В нашем примере коты, собаки, змеи — всё это питомцы (pets). Так почему бы нам не создать класс Pet, который будет «родительским» для остальных, которые, в свою очередь, будут наледовать общие для всех питомцев свойства? Пишем:
Код:
class Pet
  attr_accessor :name, :age, :gender, :color
end
class Cat < Pet
end
class Dog < Pet
end
class Snake < Pet
  attr_accessor :length
end
Принцип и правила объявления наследованных классов, думаю, понятны, теперь попробуйте создать объекты, задать параметры и вывести результат. Заметим, что более простые классы стоят выше сложных в иерархии классов.
Вернуться к началу Перейти вниз
3EH
Модератор
Модератор
3EH


Профиль
СообщениеТема: Re: Осваиваем Ruby   Осваиваем Ruby EmptyСр 06 Апр 2011, 18:22

Продолжаем штудировать Руби. На этот раз дело коснётся массивов. Но начнем с диапазонов.

Диапазоны значений
Иногда полезно иметь возможность сохранить «концепт» простого списка, причём хочется, чтобы объявить его мы могли бы максимально просто, например: список из букв от A до Z, или числа от 1 до 25. С помощью диапазонов это возможно, они в Руби максимально интуитивно понятны. Вот простые числовые диапазоны:
Код:
digits = 0..9
scale1 = 0..10
scale2 = 0...10 #digits = scale2
Оператор .. включает конечное значение, а ... — нет (глупо — казалось, что должно быть наоборот ). Однако сами по себе диапазоны мало используются.

Массивы
Простые переменные порой не годятся для реального программирования. Каждый современный ЯП, в т.ч. и Руби, поддерживает более сложные формы структурированных данных. В Руби вы можете представлять упорядоченные наборы объектов с помощью массивов.
Массивы в Руби динамические: можно (но не обязательно) указывать размер массива при создании. После этого он может расти без участия со стороны программиста, поэтому в практике редко приходится даже узнавать его размер. Массивы в Руби гетерогенные: они могут хранить данные самых разных типов данных (если быть точным, то массив хранит только ссылки на объекты). Три одинаковых массива:
Код:
a = Array.[](1,2,3,4)
b = Array[1,2,3,4]
c = [1,2,3,4]
Для создания массивов используется специальный метод класса []. Также есть метод new, который берет 0, 1 или два параметра: первый — количество элементов, второй — их значение. Смотрим пример:
Код:
d = Array.new # Создаем пустой массив
e = Array.new(3) # [nil, nil, nil]
f = Array.new(3, "ruby") # ["ruby", "ruby", "ruby"]
Частая ошибка начинающих — считаем, что элементы независимы друг от друга. Однако, как было сказано раньше, в массиве лишь ссылки на один объект. Чтобы избежать такого поведения используем блок (мы его уже встречали во второй капле — это код между {}):
Код:
f[0].capitalize! # f теперь: ["Ruby", "Ruby", "Ruby"]
g = Array.new(3) { "ruby" } # ["ruby", "ruby", "ruby"]
g[0].capitalize! # g теперь: ["Ruby", "ruby", "ruby"]
Обращение к элементам и установление их значений выполняются с помощью методов [] и []= соответственно. Каждый может принимать один или два (начало и длина) параметра или диапазон. Обратный отсчет с конца массива начинается с -1. Считывать значения можно и специальным простым методом at — он принимает только один параметр и поэтому работает немного быстрее, delete_at удалит элемент. Смотрим:
Код:
a = [1, 2, 3, 4, 5, 6]
b = a[0] # 1
c = a.at(0) # 1
d = a[-2] # 5
e = a.at(-2) # 5
f = a[9] # nil
g = a.at(9) # nil
h = a[3,3] # [4, 5, 6]
i = a[2..4] # [3, 4, 5]
j = a[2...4] # [3, 4]

a[1] = 8 # [1, 8, 3, 4, 5, 6]
a[1,3] = [10, 20, 30] # [1, 10, 20, 30, 5, 6]
a[0..3] = [2, 4, 6, 8] # [2, 4, 6, 8, 5, 6]
a[-1] = 12 # [2, 4, 6, 8, 5, 12]

a.delete_at(3) # [1, 2, 4, 5, 6]
a.delete_at(9) # nil
Другой способ — толкание (pushing) данных. Метод join «сливает» элементы массива в одну переменную, в качестве параметра указываем разделитель:
Код:
x = []
x << "Word"
x << "Play" << "Fun"
puts x.join(', ') # Word, Play, Fun
Методы first и last возвращают первый и последний элемент массива соответственно, а values_at — массив, содержащий только выбранные элементы:
Код:
x = ["alpha", "beta", "gamma", "delta", "epsilon"]
a = x.first # alpha
b = x.values_at(0..2,4) # [alpha, beta, gamma, epsilon]
Метод length и его алиас size возвратят количество элементов в массиве, а nitems не будет считать пустые элементы (nil), compact уберёт nil из массива вообще:
Код:
y = [1, 2, nil, nil, 3, 4]
c = y.size # 6
e = y.nitems # 4
d = y.compact # [1, 2, 3, 4]
Самый простой метод для сортировки массива — это sort (попробуйте сами). Сортировка работает только в массивах, содержащих элементы, которые поддаются сравнению — с массивами со смешанными типами данных метод возвратит ошибку. Отсортируем смешанный массив, налету преобразовывая его элементы в строки (преобразовываем методом to_s):
Код:
a = [1, 2, "three", "four", 5, 6]
b = a.sort {|x,y| x.to_s <=> y.to_s}
# b теперь [1, 2, 5, 6, "four", "three"]
Как это работает? <=> — один из методов сравнения (см. выше). Блок возвращает -1, если первый их сравниваемой пары элемент меньше (тогда метод меняет элементы местами), если элементы равны, 1 — если больше (в последних двух случаях оставляем элементы на местах). Поэтому для убывающего порядка надо просто поменять местами сравниваемые элементы ({|x,y| y.to_s <=> x.to_s}). Думаю, что мы всё поняли.
Для выборки элементов из массива по критериям используем detect (find — его синоним) и find_all (select — то же самое), выражение критерия засовываем в блок:
Код:
x = [5, 8, 12, 9, 4, 30]
# find покажет нам только первый элемент, кратный шести
x.find {|e| e % 6 == 0 } # 12
# А select покажет все подходящие элементы
x.select {|e| e % 6 == 0} # [12, 30]
Метод reject обратен select — он удалит каждый элемент, удовлетворяющий блоку:
Код:
x = [5, 8, 12, 9, 4, 30]
d = c.reject {|e| e % 2 == 0} # [5, 9]
delete удалит все элементы, содержащие определенные данные:
Код:
c = ["alpha", "beta", "gamma", "delta"]
c.delete("delta")
# Теперь с = ["alpha", "beta", "gamma"]
В классе массивов определен итератор each — работает он просто, догадайтесь, что делает этот код:
Код:
[1, "test", 2, 3, 4].each { |element| puts element.to_s + "X" }
Можно создать копию массива и изменить её налету с помощью итератора collect:
Код:
[1, 2, 3, 4].collect { |element| element * 2 } #[2, 4, 6, 8]
Объединяем массивы:
Код:
x = [1, 2, 3]
y = ["a", "b", "c"]
z = x + y #[1, 2, 3, "a", "b", "c"]

a = [1, 2, 3, 4]
b = [3, 4, 5, 6]
a — b # [1, 2] — разность массивов
a & b # [3, 4] — пересечение массивов
a | b # [1, 2, 3, 4, 5, 6] — объединение с удалением дупликатов
a*2 # [1, 2, 3, 4, 1, 2, 3, 4] - повторение
Вернуться к началу Перейти вниз
3EH
Модератор
Модератор
3EH


Профиль
СообщениеТема: Re: Осваиваем Ruby   Осваиваем Ruby EmptyЧт 07 Апр 2011, 17:59

Сейчас мы с вами создадим наше первое полноценное приложение на Руби, попутно обучаясь новым методам классов String и File и регулярными выражениями.

Наше приложение: Текстовый анализатор
Собственно программа простая: она будет считывать текстовый файл, анализировать его по некоторым паттернам, считать статистику и выводить результат. Руби замечательно подходит для анализа документов и текстов с помощью регулярных выражений и методов scan и split. В этом приложении мы сконцентрируемся на простом и быстром программировании и не будем организовывать объектно-ориентированную структуру.

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

Реализация
В начале разработки новой программы полезно представить неоходимы ключевые шаги. Давайте выделим основные ступени:
  • Загрузить файл, содержащий текст, который мы хотим проанализировать.
  • Так как мы загружаем файл по строками, сразу будем считать их количество для необходимой статистики.
  • Вставить весь текст в одну строку и измерить ее длину для подсчета символов.
  • Временно удалить все пробелы и посчитать длину новой строки без них.
  • Разбить строку по пробелам, чтобы узнать количество слов.
  • Разбить строку по знакам препинания, чтобы посчитать количество предложений
  • Разбить по двойным переносам строки, чтобы узнать количество абзацев.
  • Произвести подсчеты, чтобы узнать средние величины для статистики.

Создайте новый, пустой файл исходников и сохраните его как analyzer.rb.

Ищем какой-нибудь текст
Перед тем, как начать писать код, неоходимо найти кусок текста для тестов. В нашем примере мы будем использовать первую часть рассказа Оливер Твист, которую вы можете загрузить [Вы должны быть зарегистрированы и подключены, чтобы видеть эту ссылку]. Сохраните файл под именем text.txt там же, где находится analyzer.rb

Загрузка файла и подсчет строк
Настало время для кодинга! Первый шаг — загрузка файла. Руби предоставляет достаточный список методов для файловых манипуляций в классе File. Вот код, который откроет наш text.txt:
Код:
File.open("text.txt").each { |line| puts line }
Внесите код в analyzer.rb и запустите программу. В результате вы увидите бегущие по экрану строки текста.
Вы запрашиваете класс File открыть text.txt, а затем, как в случае с массивами, вызываете метод each прямо на файл, заставляя передавать каждую строку одну за другой во внутренний блок, где puts отпраляет их на экран. Отредактируйте код, чтобы он выглядел так:
Код:
line_count = 0
File.open("text.txt").each { |line| line_count += 1 }
puts line_count
Вы определяете переменную line_count, чтобы хранить в ней счетчик строк, затем окрываете файл и итерируете по строкам, увеличивая line_count на 1 каждый раз. В конце вы выводите результат на экран (около 127 в нашем примере). У нас есть первый кусочек для статистики!
Вы посчитали строки, однако у нас по-прежнему нет возможности посчитать слова, предложения, абзацы. Это легко исправить. Давайте немного изменим код и добавим переменную text, чтобы налету собрать в нее все строки:
Код:
text=''
line_count = 0
File.open("text.txt").each do |line|
  line_count += 1
  text << line
end

puts "#{line_count} lines"
В отличие от предыдущего кода, этот представляет переменную text и добавляет в нее каждую строку. Когда итерация окончена, в text находится весь наш текст.
Казалось бы код максимально лаконичен и прост, однако в File также существуют другие методы, которые могут быть использованы в нашем случае. Например, мы можем переписать наш код так:
Код:
lines = File.readlines("text.txt")
line_count = lines.size
text = lines.join

puts "#{line_count} lines"
Намного проще! Метод readlines считывает весь файл в массив, строка за строкой.

Считаем символы

Так как мы собрали весь файл в text, мы можем использовать применимый для строк метод length, который вернет размер (количество символов) в строке, и, соответственно, во всем нашем тексте. Допишем код:
Код:
total_characters = text.length
puts "#{total_characters} characters"
Еще один элемент статистики, который нам необходим — это подсчёт символов без пробелов. Для этого воспользуемся методами замены символов. Вот пример:
Код:
puts "foobar".sub('bar', 'foo') #foofoo
Метод sub нашел набор символов, переданный в первом параметре, и заменил их на символы из второго. Однако sub находит и изменяет только одно, первое встретившееся вхождение символов, метод gsub производит все возможные замены за раз.

Регулярные выражения
А как насчет замены более сложных патернов? Для этого используются регулярные выражения (regular expression). Целые книги были написаны на эту тему, поэтому мы ограничимся лишь кратким обзором этого мощного инструмента для работы с текстом. В Руби регулярные выражения создаются с помощью заключения патерна между слэшами (/pattern/). И в Руби, естественно, это также объекты. Например, вы можете задать следующий патерн для того, чтобы выбрать строки, содержащие текст Perl или текст Python: /Perl|Python/. В слэшах заключен наш патерн, состоящий из двух необходимых нам слов, разделенных прямой чертой (пайпом, pipe, |). Это символ означает «или то, что слева, или то, что справа». Вы также можете использовать скобки, как в числовых выражениях: /P(erl|ython)/.
В патернах можно реализовать повторения: /ab+c/ (это не сложение, рассматриваем как a, затем b+, затем с). Такому патерну соответствует строка, содержащая вхождение a, затем одного или более b, и, наконец, с. Заменим плюс на звездочку, теперь /ab*c/ соответствует строка содержащая a, ноль или больше b и с. + и * — это так называемые квантификаторы, чьё назначение, я думаю, понятно
Мы также можем выбирать строки, содержащие определенные символы. Наиболее простой пример — это патерны классов символов, например, \s означает whitespace (это пробелы, табы, переносы строки и т. п.), под \d попадают все числа, и др. Вот сводка, взятая из учебника по Руби на Wikibooks:
[Вы должны быть зарегистрированы и подключены, чтобы видеть это изображение]

Продолжаем считать символы
Для подсчета количества слов есть два подхода:
  • Посчитать число групп непрерывных символов, используя метод scan
  • Разбить текст по пробельным символам и посчитать получившиеся фрагменты с помощью split и size.

Пойдем по второму пути. По умолчанию (без параметров) split разобьет строку по пробельным символам и поместит фрагменты в массив. Нам остается только узнать длину массива. Дописываем код:
Код:
word_count = text.split.length
puts "#{word_count} words"

Считаем предложения и абзацы
Если нам понятно, как был реализован подсчет символов, то с предложениями и абзацами сложностей не будет. Единственное отличие в патерне, по которому мы разбиваем текст. Для предложения это точка, вопросительный и восклицательный знаки, для абзацев — двойной перенос строки. Вот код:
Код:
paragraph_count = text.split(/\n\n/).length
puts "#{paragraph_count} paragraphs"
sentence_count = text.split(/\.|\?|!/).length
puts "#{sentence_count} sentences"
Думаю, код понятен. Единственную сложность может составить патерн у предложений. Однако, он только выглядит страшно. Мы не можем просто ставить символы . и ? — мы их «экранируем» наклонной чертой.

Подсчет остальных значений
У нас уже есть количество слов, абзацев и предложений в переменных word_count,
paragraph_count и sentence_count соответственно, поэтому дальше работает только арифметика:
Код:
puts "#{sentence_count / paragraph_count} sentences per paragraph (average)"
puts "#{word_count / sentence_count} words per sentence (average)"

Исходный код
Мы дополняли исходный код шаг за шагом, поэтому логика и вывод на экран у нас смешались. Давайте расставим все на свои места. Далее только косметические изменения:
Код:
lines = File.readlines("text.txt")
line_count = lines.size
text = lines.join
word_count = text.split.length
character_count = text.length
character_count_nospaces = text.gsub(/\s+/, '').length
paragraph_count = text.split(/\n\n/).length
sentence_count = text.split(/\.|\?|!/).length

puts "#{line_count} lines"
puts "#{character_count} characters"
puts "#{character_count_nospaces} characters excluding spaces"
puts "#{word_count} words"
puts "#{paragraph_count} paragraphs"
puts "#{sentence_count} sentences"
puts "#{sentence_count / paragraph_count} sentences per paragraph (average)"
puts "#{word_count / sentence_count} words per sentence (average)"
Вернуться к началу Перейти вниз
3EH
Модератор
Модератор
3EH


Профиль
СообщениеТема: Re: Осваиваем Ruby   Осваиваем Ruby EmptyПт 08 Апр 2011, 08:26

А теперь мы еще раз пробежимся по всем рассмотренным нами темам и углубимся в них в поисках упущенного и интересного.

Ввод и inspect
Код:
puts "What is your name?"
STDOUT.flush
chompname = gets.chomp
puts "Again, what is your name?"
name = gets
puts "Hello, " + name
puts "Hi, " + chompname
puts 'But name = ' + name.inspect + ' and chompname = ' + chompname.inspect
STDOUT — стандартная глобальная константа, обозначающая стандартный канал вывода. Метод flush очищает все данные во внутреннем буфере ввода/вывода Руби. Использование этой строки кода необязательно, но рекомендуется. Помним, что все константы должны начинаться с заглавной буквы.
gets принимает одну строку введенных данных и передает его переменной. chomp — это метод класса String. Несмотря на то, что результат мы видим одинаковый, необходимо помнить, что gets возвращает строку и \n, в то время как chomp удаляет этот \n (метод также удаляет возврат каретки \r и комбинацию \r\n).
Легко продемонстрировать это с помощью метода inspect, роль которого «заглядывать» в переменные, классы — в общем в любые объекты Руби.

Пунктуация в методах
Восклицательный знак в конце метода означает, что он не только возвращает результат, но и изменяет объект, к которому он применен (это так называемый «опасный» метод). Метод strip убирает непечатные и пробельные символы в начале и конце строки:
Код:
string = 'Bring, bring    '
a = string.strip!
puts string
puts a
Методы с вопросительным знаком, так называемые предикаты, возвращают только true или false, например, метод массивов empty? вернет true, если если в массиве нет элементов:
Код:
a = []
puts "empty" if a.empty?
Метод any? наоборот вернет true, если в массиве элементы присутствуют, а nonzero?, определенный в классе Numeric, выдаст nil, если число, на которое он вызван, равно нулю, в противном случае вернет это число.

Используем %w

Порой создание массива из слов может быть большой головной болью, однако в Руби есть упрощение для этого: %w{} делает то, что нам нужно:
Код:
pets1 = [ 'cat', 'dog', 'snake', 'hamster', 'rat' ]
pets2 = %w{ cat dog snake hamster rat } # pets1 = pets2

Ветвление по условиям
Мы уже говорили о том, что выражения условий позволяют контролировать направления выполнения кода. Повторим эти выражения и узнаем новые.
if
Код:
a = 7
if a == 4
  a = 9
end
Но Руби не был бы Руби, если б не упрощал нам задачу. Полностью аналогичный цикл:
Код:
a = 7
a = 9 if a == 4
if-elsif-else
Пример условия:
Код:
a = 7
if a == 4
  a = 9
else
  if a == 7
      a = 10
  end
end
elsif максимально упростит это условие и получаем:
Код:
a = 7
if a == 4
  a = 9
elsif a == 7
  a = 10
end

Трёхместный оператор
Код:
a = 7
plus_minus = '+'
print "#{a} #{plus_minus} 2 = " + (plus_minus == '+' ? (a+2).to_s : (a-2).to_s)
Конструкция [? (expr) : (expr)] называется трёхместным (ternary) оператором (единственный трехместный в Руби) и служит для подсчета выражения и возвращения результата. Рекомендуется использовать только для второстепенных задач, так как подобный код тяжело воспринимается. Подсчитывается сначала первый операнд перед ?, если его значение не false и не nil, значением выражения становится значение второго операнда, иначе — третьего (после :).

while
while в Руби синтаксически похож на if и while в других ЯП:
Код:
a = 0
while a < 5
  puts a.to_s
  a += 1
end
Как обычно цикл можно поместить в одну строку: <...код...> while <выражение>
Для построения структуры проверки условия после выполнения тела цикла в руби чаще всего используется:
Код:
begin
puts 1
end while false
В случае begin <code> end while <cond> код обязательно выполнится хотя бы 1 раз, тогда как в случае <code> while <cond> может ни разу не выполниться, потому что это эквивалентно записи while <cond> <code>

Символы (Symbols)
В коде Symbol выглядит как имя переменной, только начинающееся с :, например, :action. Symbol — самый простой объект в Руби, который возможно создать — у него есть только имя и ID. Symbol'ы более эфективны, производительны, чем строки, — данное имя для symbol ссылается на один объект на протяжении всей программы, в то время как две строки с одинаковым содержанием являются разными объектами — это сохраняет время и память:
Код:
ruby_know = :yes
if ruby_know == :yes
  puts "You're a good guy!"
else
  puts 'Learn Ruby!'
end
В этом примере :yessymbol, он не содержит значений или объектов, вместо этого он используется как постоянное имя в коде. Мы можем преспокойно заменить :yes на строку "yes", результат будет такой же, но программа будет менее производительной. Более подробно это мы рассматривать не будем, на начальном этапе этих знаний нам вполне достаточно.

Ассоциативные массивы
Асоциативные массивы (далее хэши, hashes) похожи на массивы, так как они также содержат упорядоченный набор объектов. Однако в массиве объекты индексируются числами, а в хэше индексом может быть любой объект. Простой пример:
Код:
h = {'dog' => 'sobaka', 'cat' => 'koshka', 'donkey' => 'oslik'}
puts h.length  # 3
puts h['dog']  # 'sobaka'
puts h        # catkoshkadonkeyoslikdogsobaka
Как видим элементы хэша не упорядочиваются, поэтому хэши непригодны для списков, очередей и т.д.
Везде, где вы хотите поставить строку в кавычках, задумайтесь о применении symbol:
Код:
users = Hash.new
users[:nickname] = 'MaxElc'
users[:language] = 'Russian'
puts users[:nickname] #MaxElc

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

Осваиваем Ruby

Предыдущая тема Следующая тема Вернуться к началу 

 Похожие темы

-
» Осваиваем Ruby (обсуждение)
Страница 1 из 1

Права доступа к этому форуму:Вы не можете отвечать на сообщения
Детский садик - Форум :: Программное обеспечение :: Программирование-
Перейти:  
Web ICQСоздать форум | ©phpBB | Бесплатный форум поддержки | Сообщить о нарушении | Последние обсуждения