Хэл Фултон - Программирование на языке Ruby
- Название:Программирование на языке Ruby
- Автор:
- Жанр:
- Издательство:ДМК Пресс
- Год:2007
- Город:Москва
- ISBN:5-94074-357-9
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Хэл Фултон - Программирование на языке Ruby краткое содержание
Ruby — относительно новый объектно-ориентированный язык, разработанный Юкихиро Мацумото в 1995 году и позаимствовавший некоторые особенности у языков LISP, Smalltalk, Perl, CLU и других. Язык активно развивается и применяется в самых разных областях: от системного администрирования до разработки сложных динамических сайтов.
Книга является полноценным руководством по Ruby — ее можно использовать и как учебник, и как справочник, и как сборник ответов на вопросы типа «как сделать то или иное в Ruby». В ней приведено свыше 400 примеров, разбитых по различным аспектам программирования, и к которым автор дает обстоятельные комментарии.
Издание предназначено для программистов самого широкого круга и самой разной квалификации, желающих научиться качественно и профессионально работать на Ruby.
Программирование на языке Ruby - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
a["flat"] # 3
а.[]("flat") # 3
a.fetch("flat") # 3
a["bent"] # nil
Предположим, что мы не уверены, существует ли объект Hash
, но хотели бы избежать очистки имеющегося хэша. Очевидное решение — проверить, определен ли интересующий нас объект:
unless defined? а
а={}
end
a["flat"] = 3
Но есть и другой способ:
а ||= {}
a["flat"] = 3
# Или даже так:
(а ||= {})["flat"] = 3
Тот же вопрос можно поставить для отдельных ключей, когда новое значение следует присваивать, лишь если такого ключа еще нет:
a=Hash.new(99)
а[2] # 99
а # {}
а[2] ||= 5 # 99
а # {}
b=Hash.new
b # {}
b[2] # nil
b[2] ||= 5 # 5
b # {2=>5}
Отметим, что nil может выступать и в качестве ключа, и в качестве значения:
b={}
b[2] # nil b[3]=nil
b # {3=>nil}
b[2].nil? # true
b[3].nil? # true b[nil]=5
b # {3=>nil,nil=>5}
b[nil] # 5
b[b[3]] # 5
8.2.4. Удаление пар ключ-значение
Удалить пары ключ-значение из хэша можно с помощью методов clear
, delete
, delete_if
, reject
, reject!
и shift
.
Метод clear
удаляет из хэша все пары. Эффект такой же, как от присваивания переменной нового пустого хэша, но работает чуть быстрее.
Метод shift
удаляет незаданную пару ключ-значение и возвращает ее в виде массива из двух элементов или nil
, если никаких ключей не осталось.
a = {1=>2, 3=>4}
b = a.shift # [1,2]
# а равно {3=>4}
Метод delete
удаляет конкретную пару ключ-значение. Он принимает в качестве параметра ключ и возвращает ассоциированное с ним значение, если такой ключ существовал (и был удален). В противном случае возвращается значение по умолчанию. Метод также принимает блок, который вырабатывает уникальное значение по умолчанию вместо того, чтобы возвращать ссылку на общий объект.
a = (1=>1, 2=>4, 3=>9, 4=>16)
a.delete(3) # 9
# a is now {1=>1, 2 =>4, 4=>16)
a.delete(5) # в этом случае nil.
delete(6) { "не найдено" } # "не найдено".
Пользуйтесь методами delete_if
, reject
или reject!
в сочетании с обязательны блоком, чтобы удалить все ключи, для которых блок возвращает значение true
. Метод reject
работает с копией хэша, а метод reject!
возвращает nil
, если не было произведено никаких изменений.
8.2.5. Обход хэша
В классе Hash
имеется стандартный итератор each
, а кроме него итераторы each_key
, each_pair
и each_value
( each_pair
— синоним each
).
{"а"=>3, "b"=>2}.each do |key, val|
print val, " из ", key, "; " # 3 из a; 2 из b;
end
Остальные два итератора передают в блок только ключ или только значение:
{"а"=>3,"b"=>2}.each_key do |key|
print "ключ = #{key};" # Печатается: ключ = a; key = b;
end
{"a"=>3,"b"=>2).each_value do |value|
print "значение = #{value};" # Печатается: значение = 3; val = 2;
end
8.2.6. Инвертирование хэша
Инвертирование хэша осуществляется в Ruby тривиально с помощью метода invert
:
а = {"fred"=>"555-1122","jane"=>"555-7779"}
b = a.invert
b["555-7779"] # "jane"
Поскольку ключи в хэше уникальны, такая операция может привести к потере данных. Значения-дубликаты будут преобразованы в уникальный ключ, которому соответствует какое-то одно из множества прежних значений. Предсказать, какое именно, невозможно.
8.2.7. Поиск ключей и значений в хэше
Определить, было ли присвоено значение некоторому ключу, позволяет метод has_key?
или любой из его синонимов include?
, key?
, member?
:
а = {"а"=>1,"b"=>2}
a.has_key? "с" # false
a.include? "а" # true
a.key? 2 # false
a.member? "b" # true
Можно также воспользоваться методом empty?
, чтобы узнать, остался ли в хэше хотя бы один ключ. А метод length
и его синоним size
позволяют узнать, сколько ключей имеется в хэше:
a.empty? # false
a.length # 2
Можно проверить также, существует ли указанное значение. Для этого предназначены методы has_value?
или value?
:
a.has_value? 2 # true
a.value? 99 # false
8.2.8. Копирование хэша в массив
Чтобы преобразовать весь хэш в массив, пользуйтесь методом to_a
. В получившемся массиве ключи станут элементами с четными индексами (начиная с 0), а значения — с нечетными:
h = {"а"=>1,"b"=>2}
h.to_a # ["а",1,"b",2]
Можно также получить массив, содержащий только ключи или только значения:
h.keys # ["а","b"]
h.values # [1,2]
Наконец, можно поместить в массив только значения, соответствующие заданному списку ключей. Этот метод работает для хэшей примерно так же, как одноименный метод для массивов. (Кроме того, как и в случае массивов, метод values_at
заменяет устаревшие методы indices
и indexes
.)
h = {1=>"one", 2=>"two", 3=>"three", 4=>"four", "cinco"=>"five"}
h.values_at(3,"cinco",4) # ["three","five","four"]
h.values_at(1,3) # ["one","three"]
8.2.9. Выборка пар ключ-значение по заданному критерию
К классу Hash
подмешан модуль Enumerable
, поэтому можно обращаться к методам detect
( find
), select
( find_all
), grep
, min
, max
и reject
(как и для массивов).
Метод detect
(синоним find
) находит одну пару ключ-значение. Он принимает блок (которому передается по одной паре за раз) и возвращает первую пару, для которой вычисление блока дает true
.
names = {"fred"=>"jones","jane"=>"tucker", "joe"=>"tucker","mary"=>"SMITH"}
# Найти tucker.
names.detect {|k,v| v=="tucker" } # ["joe","tucker"]
# Найти имена, записанные прописными буквами.
names.find {|k,v| v==v.upcase } # ["mary", "SMITH"]
Разумеется, объекты в хэше могут быть сколь угодно сложными, как и условие, проверяемое в блоке, но сравнение объектов разных типов может оказаться проблематичным.
Метод select
(синоним find_all
) возвращает все пары, удовлетворяющие условию, а не только первую:
names.select {|k,v| v=="tucker" }
# [["joe", "tucker"], ["jane", "tucker"]]
names.find_all (|k,v| k.count("r")>0}
# [["mary", "SMITH"], ["fred", "jones"]]
8.2.10. Сортировка хэша
Хэши по природе своей не упорядочены ни по ключам, ни по значениям. Чтобы отсортировать хэш, Ruby преобразует его в массив, который затем сортирует. Понятно, что и результатом является массив.
names = {"Jack"=>"Ruby","Monty"=>"Python",
"Blaise"=>"Pascal", "Minnie"=>"Perl"} list = names.sort
# list равно:
# [["Blaise","Pascal"], ["Jack","Ruby"],
# ["Minnie","Perl"], ["Monty","Python"]]
8.2.11. Объединение двух хэшей
Иногда бывает нужно объединить хэши. Метод merge
получает два хэша и формирует из них третий, перезаписывая обнаружившиеся дубликаты:
dict = {"base"=>"foundation", "pedestal"=>"base"}
Интервал:
Закладка: