Глава 2 Заметки о шаблонах проектирования в Ruby, Расс Олсен
Расс Олсен
в своей книге "Паттерны проектирования в Ruby"
позволяет новичкам в этом языке легко просмотреть отличное введение о Ruby, которое поможет создавать лучшие программы.
В этой статье я обобщаю заметки, которые я написал о главе 2.
Ознакомьтесь с главой 1 здесь 👇👇
Начало работы с Ruby
Самый простой способ запустить язык Ruby - использовать интерактивную оболочку Ruby,
irb
.
- Вы можете запускать в оболочке в интерактивном режиме:
$ irb
irb(main):001:0> 2 + 2
=> 4
irb(main):002:0>
- Вы можете запустить программу на Ruby с помощью команды
ruby
(интерпретатор Ruby):
$ ruby hello.rb
hello world
где hello.rb
:
puts 'hello world'
Как видите, puts
выводит значения, а функция в Ruby может принимать параметры без скобок.
Также в Ruby вычисления могут продолжаться во второй строке, как в calc.rb
файле:
x = 1 +
2 + 3
puts x
запуск файла:
$ ruby calc.rb
6
Будьте осторожны, если вы продолжите строку до того, как желаемый оператор закончится следующим образом:
x = 1
+ 2 + 3
puts x
он даст вам 1. Если вы хотите добавить 2 и 3, вы должны расширить первую строку с помощью /
:
x = 1 \
+ 2 + 3
puts x
- Для имен переменных хорошо воспитанный программист на Ruby использует words_separated_by_underscores вместо camelCase.
- В Ruby константы начинаются с заглавной буквы. Не следует изменять значение константы, хотя вы можете изменить его, но вы получите предупреждение о возникшей проблеме.
Pounds = 2.2
FACTS = 'Life and Death'
/
выполняет целочисленное деление в Ruby:
6/3 # is 2
7/3 # is still 2
- Все в Ruby - это объект. С помощью метода класса вы можете узнать его тип:
irb(main):012:0> 7777777777777777777.class
=> Integer
irb(main):013:0> 77.77777777777777777.class
=> Float
irb(main):014:0> 'str'.class
=> String
Вы можете проверить тип объекта instance_of
методом. Вы можете проверить, равен ли он нулю, nil
методом. Вы также можете преобразовать объект в строку с помощью метода to_s
.
irb(main):023:0> 'hello'.instance_of? String
=> true
irb(main):021:0> 'hello'.nil?
=> false
irb(main):022:0> 44.to_s
=> "44"
Поскольку все в Ruby является объектами, нельзя сказать, что выражение x = 44 присваивает значение 44 переменной x. Вместо этого на самом деле происходит то, что x получает ссылку на объект, который представляет число после 43.
nil
иfalse
оба имеют значение false:
nil || false # false
nil or false # false
как вы могли догадаться, ||
и or
являются логическим оператором OR, а &&
и and
- оператором AND. Также not
и !
одинаковы для отрицания.
Если вы пришли из мира C или C ++, вы будете шокированы, узнав, что в Ruby ноль, не являясь ни
false
, ниnil
, в логическом выражении оценивается какtrue
. Удивительно, но это выражение:
if 0
puts 'Zero is true'
else
puts 'Zero is false'
end
распечатает
Zero is true
- Иначе, если в Ruby это
elsif
- В Ruby есть оператор
unless
, который переворачивает операторif
:
unless weight < 100
puts 'way too heavy'
end
Также доступна краткая форма:
puts 'way too heavy' unless weight < 100
- Программисты Ruby обычно пишут такие циклы:
array = ['first', 'second', 'third']
array.each do |element|
puts element
end
вместо цикла for
:
for element in array
puts element
end
until
- злой двойник петлиwhile
; отменяет условие.- Некоторые методы для строк в Ruby:
irb(main):001:0> name = 'Ezz'
=> "Ezz"
irb(main):002:0> name.length
=> 3
irb(main):003:0> name.upcase
=> "EZZ"
irb(main):004:0> name.downcase
=> "ezz"
- Во многих отношениях строки Ruby действуют как массивы; изменчивый:
irb(main):005:0> name[0] = 'Z'
=> "Z"
irb(main):006:0> name
=> "Zzz"
- Подстановка внутри строки выполняется
#{expression}
n = 42
puts "The value of n is #{n}."
который распечатывает:
The value of n is 42
Позаботьтесь, чтобы строка, содержащая подстановку, была заключена в двойные кавычки.
Символы - это более или менее неизменяемые строки, и программисты Ruby используют их как идентификаторы:
:a_symbol
:an_other_symbol
:first_name
Например, здесь нельзя редактировать str2:
str1 = 'Ezz'
str2 = :Ezz
str1[0] = 'Z'
# str2[0] = 'Z'
puts str1
puts str2
- Добавление массивов в Ruby может быть выполнено с помощью оператора
<<
:
a = ['banana', 'apple', 'orange']
a << 'mango'
puts a # ['banana', 'apple', 'orange', 'mango']
Вы можете отсортировать или перевернуть массив. Если вы хотите изменить массив на месте (изменения происходят с исходным массивом), добавьте !
в метод.
a = ['banana', 'apple', 'orange']
a << 'mango'
a.sort
puts "original array not sorted: #{a}"
a.reverse
puts "original array not reversed: #{a}"
a.sort!
puts "original array sorted: #{a}"
a.reverse!
puts "original array reversed: #{a}"
- Вы можете создавать хэши в Ruby с помощью пары скобок:
h = {}
h['first_name'] = 'Abu Bakr'
h['last_name'] = 'El Seddiq'
puts h
h_new = {'first_name' => 'Abu Bakr', 'last_name' => 'El Seddiq'}
puts h_new
Символы - хорошие хеш-ключи:
h_improved = {:first_name => 'Abu Bakr', :last_name => 'El Seddiq'}
puts h_improved
- Регулярные выражения в Ruby помещаются между парой косых черт. Оператор
=~
при сопоставлении RE со строкой и!~
для проверки того, не соответствует ли RE:
/old/ =~ 'this old house' # 5 - the index of 'old'
/new/ !~ 'this old house' # true - 'new' is not matching anything
/Russ|Russel/ =~ 'Fred' # nil - Fred is not Russ nor Russel
/.x*/ =~ 'any old string' # 0 - the RE will match anything
Классы
class BankAccount def initialize account_owner @owner = account_owner @balance = 0 end
def deposit amount @balance = @balance + amount end
def withdraw amount @balance = @balance - amount end end
- Классы в Ruby начинаются с заглавных букв и используют верблюжий регистр
- Метод
initialize
особенный, это Ruby-версия конструктора. - Чтобы создать новый экземпляр нашего класса BankAccount
my_account = BankAccount.new('Ezz')
- Допустим, я хочу получить доступ к переменной экземпляра balance:
my_account = BankAccount.new('Ezz')
puts my_account.balance
похоже, что этот код не работает и выдает следующую ошибку:
BankAccount.rb:17:in `<main>': undefined method `balance' @owner="Ezz", @balance=0> (NoMethodError)
Это связано с тем, что к переменной экземпляра объекта Ruby нельзя получить доступ за пределами объекта. Вот почему мы определяем метод доступа:
def balance
@balance
end
Если мы добавим это в класс BankAccount и попытаемся получить баланс, мы получим 0.
Возможно, мы захотим установить новый баланс, поэтому мы добавляем метод setter:
def set_balance new_balance
@balance = new_balance
end
Если вы попытались расслабиться и проигнорировать просто метод установки и написали это:
my_account.balance = 100
он выведет NoMethodError
. Что вам нужно сделать вместо этого и вместо уродливого метода установки:
def balance=(new_balance)
@balance = new_balance
end
который мы можем использовать для установки баланса, используя:
my_account.balance=(100)
и, как всегда в Ruby, скобки можно опустить.
То, что мы сделали выше, - это уловка, с помощью которой Ruby узнает, что balance=
- это метод, который принимает один аргумент. Да, как вы могли понять, этот знак равенства является частью имени метода, которое Ruby переводит в простой вызов старого метода.
Итак, теперь класс выглядит хорошо со стороны внешнего мира. У нас есть balance
; метод получения и balance=
; метод для установки.
Скучно, правда?
Неудивительно, что у Руби есть решение. Поскольку Ruby-программисты часто используют методы получения и установки. Ruby предлагает нам отличный ярлык:
attr_accessor :balance
Теперь этот оператор создает значение переменной экземпляра @balance, чтобы можно было получить. Он также создает метод установки balance=(new_value)
.
Что, если вы хотите просто получить доступ к переменной экземпляра, а не устанавливать ее? В этом случае вы можете использовать attr_reader
так:
attr_reader :name
в этом случае имя переменной доступно только для чтения.
Точно так же только для метода установки используйте attr_writer
.
- Иногда методу нужна ссылка на текущий объект, мы можем использовать
self
:
class SelfCentered def talk_about_me puts "Hello I am #{self}" end end
conceited = SelfCentered.new conceited.talk_about_me
но когда вы запустите этот код, вы получите что-то вроде этого:
Hello I am #<SelfCentered:0x00005600a5ccfa78>
указывающий на шестнадцатеричный адрес экземпляра SelfCentered
.
- Ruby поддерживает одиночное наследование - все классы, которые вы создаете, имеют ровно один родительский элемент суперкласса. Если суперкласс не указан, ваш класс автоматически становится подклассом
Object
.
В этом примере мы создадим подкласс BankAccount
:
class InterestingBearingAccount < BankAccount def initialize owner, rate @owner = owner @balance = 0 @rate = rate end
def deposit_interest @balance += @rate * @balance end end
Если вы сравните это с суперклассом BankAccount
, вы увидите дублирующуюся информацию в методе initialize
. У нас есть те же owner
и balance
, что и в initialize
методе BankAccount
:
def initialize account_owner
@owner = account_owner
@balance = 0
end
В этом случае лучше избегать этого беспорядочного дублирования кода, и мы должны использовать super
метод следующим образом:
def initialize owner, rate
super(owner)
@rate = rate
end
Когда метод вызывает
super
, он говорит: «Найдите метод с тем же именем, что и у меня, в моем суперклассе и вызовите его».
В общем, то, что делает super
, - это то, что он вызывает метод initialize
в суперклассе BankAccount
. Если этот метод не существует в первом суперклассе, Ruby продолжит работу в корне наследования, пока не найдет этот конкретный метод.
Аргументы
- Вы можете установить значение по умолчанию в функции Ruby, например:
def add_args name, car="BMW" puts "#{name} has #{car}" end
add_args("Ezz") add_args("Ezz", "Rolls Royce")
При первом возврате будет сказано, что у меня BMW, а при втором возврате будет сказано, что я стал богаче и имею Rolls Royce.
- Для списка аргументов вы можете использовать звездочки:
def describe_langs name, *languages puts "#{name}" for lang in languages puts "learns: #{lang}" end end
describe_langs("Ezz", "Python", "MATLAB", "Javascript", "Rust")
Модули
- В Ruby вы можете включить модуль внутри класса, но вы можете создать экземпляр из модуля.
module Chatty def say_hi puts "Hello, my name is #{name}" puts "My job title is #{title}" end end
class Employee include Chatty
def name 'Ezz' end
def title 'Data Engineer' end end
employee = Employee.new puts employee.say_hi
так что вы не можете сделать что-то вроде этого:
employee = Chatty.new
puts employee.say_hi
Исключение
- Ruby перехватит любое исключение с ключевым словом
rescue
. Вы также можете указать тип исключения:
begin
quotient = 1 / 0
rescue ZeroDivisionError
puts "Division by zero"
end
Если вы хотите вызвать исключение, вы можете использовать raise
.
Импорт исходных файлов
- В Ruby вы можете импортировать исходные файлы с помощью
require
, который загружает классы внутри Ruby с указанным именем файла. Импортируйте такие классы:
require 'account.rb'
or
require 'account'
Это также относится к стандартным файлам, включенным в Ruby. Например, вы можете анализировать некоторые URL-адреса с помощью класса URI, который поставляется с Ruby:
require 'uri'
ezz = URI.parse 'https://wwww.ezzeddinabdullah.com'
- Допустим, вам нужен пакет под названием runt, который существует в RubyGems; система упаковки программного обеспечения. Затем вам нужно потребовать RubyGems перед самим пакетом:
require 'rubygems'
require 'runt'
Последние мысли
В этой главе мы кратко познакомились с языком Ruby.
Мы видели, что все в Ruby, от строки до числа и массивов, является объектами. Здесь автор завершает Ruby для начинающих, чтобы вы могли использовать его для создания более совершенных программ, реализующих шаблоны проектирования. Следите за обновлениями, потому что мы собираемся начать.
Увидимся в примечаниях к главе 3!
Получите Паттерны дизайна на Ruby от Amazon !!
Раскрытие информации: ссылка на книгу на Amazon (в этом разделе) является платной, поэтому, если вы купите книгу, я получу небольшую комиссию
Первоначально опубликовано
Изучение основ Ruby за‹ 9 минут от ЭззЭддина Абдуллы
Расс Олсен в своей книге «Шаблоны проектирования в Ruby позволяет новичкам в этом языке просмотреть отличное вступление… www.ezzeddinabdullah.com »