Хэл Фултон - Программирование на языке Ruby
- Название:Программирование на языке Ruby
- Автор:
- Жанр:
- Издательство:ДМК Пресс
- Год:2007
- Город:Москва
- ISBN:5-94074-357-9
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Хэл Фултон - Программирование на языке Ruby краткое содержание
Ruby — относительно новый объектно-ориентированный язык, разработанный Юкихиро Мацумото в 1995 году и позаимствовавший некоторые особенности у языков LISP, Smalltalk, Perl, CLU и других. Язык активно развивается и применяется в самых разных областях: от системного администрирования до разработки сложных динамических сайтов.
Книга является полноценным руководством по Ruby — ее можно использовать и как учебник, и как справочник, и как сборник ответов на вопросы типа «как сделать то или иное в Ruby». В ней приведено свыше 400 примеров, разбитых по различным аспектам программирования, и к которым автор дает обстоятельные комментарии.
Издание предназначено для программистов самого широкого круга и самой разной квалификации, желающих научиться качественно и профессионально работать на Ruby.
Программирование на языке Ruby - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
z2 = 3 + 5*Complex::I # z2 == z1
После загрузки библиотеки complex
некоторые стандартные математические функции изменяют свое поведение. Тригонометрические функции — sin
, sinh
, tan
и tanh
(а также некоторые другие, например, ехр
и log
) начинают принимать еще и комплексные аргументы. Некоторые функции, например sqrt
, даже возвращают комплексные числа в качестве результата.
x = Math.sqrt(Complex(3,5)) # Приближенно Complex(2.1013, 1.1897)
y = Math.sqrt(-1) # Complex(0,1)
Дополнительную информацию ищите в любой полной документации, в частности на сайте ruby-doc.org.
5.12. Библиотека mathn
В программах, выполняющих большой объем математических вычислений, очень пригодится замечательная библиотека mathn
, которую написал Кейдзу Исидзука (Keiju Ishitsuka). В ней есть целый ряд удобных методов и классов; кроме того, она унифицирует все классы Ruby для работы с числами так, что они начинают хорошо работать совместно.
Простейший способ воспользоваться этой библиотекой — включить ее с помощью директивы require
и забыть. Поскольку она сама включает библиотеки complex
, rational
и matrix
(в таком порядке), то вы можете этого не делать.
В общем случае библиотека mathn
пытается вернуть «разумные» результаты вычислений. Например, при извлечении квадратного корня из Rational
будет возвращен новый объект Rational
, если это возможно; в противном случае Float
. В таблице 5.1 приведены некоторые последствия загрузки этой библиотеки.
Таблица 5.1. Результаты вычислений в случае отсутствия и наличия библиотеки mathn
Выражение | Без mathn | С mathn |
---|---|---|
Math.sqrt(Rational(9,16)) | 0.75 | Rational(3,4) |
1/2 | 0 | Rational(1,2) |
Matrix.identity(3)/3 | Matrix[[0,0,0], [0,0,0],[0,0,0]] | Matrix[[1/3,0,0], [0,1/3,0],[0,0,1/3]] |
Math.sqrt(64/25) | 1.4142… | Rational(8,5) |
Rational(1,10).inspect | Rational(1,10) | 1/10 |
Библиотека mathn
добавляет методы **
и power2
в класс Rational
. Она изменяет поведение метода Math.sqrt
и добавляет метод Math.rsqrt
, умеющий работать с рациональными числами.
Дополнительная информация приводится в разделах 5.13 и 5.14.
5.13. Разложение на простые множители, вычисление НОД и НОК
В библиотеке mathn
определены также некоторые новые методы в классе Integer
. Так, метод gcd2
служит для нахождения наибольшего общего делителя (НОД) объекта, от имени которого он вызван, и другого числа.
n = 36.gcd2(120) # 12 k = 237.gcd2(79) # 79
Метод prime_division
выполняет разложение на простые множители. Результат возвращается в виде массива массивов, в котором каждый вложенный массив содержит простое число и показатель степени, с которым оно входит в произведение.
factors = 126.prime_division # [[2,1], [3,2], [7,1]]
# To есть 2**1 * 3**2 * 7**1
Имеется также метод класса Integer.from_prime_division
, который восстанавливает исходное число из его сомножителей. Это именно метод класса, потому что выступает в роли «конструктора» целого числа.
factors = [[2,1],[3,1],[7,1]]
num = Integer.from_prime_division(factors) # 42
Ниже показано, как разложение на простые множители можно использовать для отыскания наименьшего общего кратного (НОК) двух чисел:
require 'mathn'
class Integer
def lcm(other)
pf1 = self.prime_division.flatten
pf2 = other.prime_division.flatten
h1 = Hash[*pf1]
h2 = Hash[*pf2]
hash = h2.merge(h1) {|key,old,new| [old,new].max }
Integer.from_prime_division(hash.to_a)
end
end
p 15.1cm(150) # 150
p 2.1cm(3) # 6
p 4.1cm(12) # 12
p 200.1cm(30) # 600
5.14. Простые числа
В библиотеке mathn
есть класс для порождения простых чисел. Итератор each
возвращает последовательные простые числа в бесконечном цикле. Метод succ
порождает следующее простое число. Вот, например, два способа получить первые 100 простых чисел:
require 'mathn'
list = []
gen = Prime.new
gen.each do |prime|
list << prime
break if list.size == 100
end
# или:
list = []
gen = Prime.new
100.times { list << gen.succ }
В следующем фрагменте проверяется, является ли данное число простым. Отметим, что если число велико, а машина медленная, то на выполнение может уйти заметное время:
require 'mathn'
class Integer
def prime?
max = Math.sqrt(self).ceil
max -= 1 if max % 2 == 0
pgen = Prime.new
pgen.each do |factor|
return false if self % factor == 0
return true if factor > max
end
end
end
31.prime? # true
237.prime? # false
1500450271.prime? # true
5.15. Явные и неявные преобразования чисел
Программисты, только начинающие изучать Ruby, часто удивляются, зачем нужны два метода to_i
и to_int
(и аналогичные им to_f
и to_flt
). В общем случае метод с коротким именем применяется для явных преобразований, а метод с длинным именем — для неявных.
Что это означает? Во-первых, в большинстве классов определены явные конверторы, но нет неявных. Насколько мне известно, методы to_int
и to_flt
не определены ни в одном из системных классов.
Во-вторых, в своих собственных классах вы, скорее всего, будете определять неявные конверторы, но не станете вызывать их вручную (если только не заняты написанием «клиентского» кода или библиотеки, которая пытается не конфликтовать с внешним миром).
Следующий пример, конечно, надуманный. В нем определен класс MyClass
, который возвращает константы из методов to_i
и to_int
. Такое поведение лишено смысла, зато иллюстрирует идею:
class MyClass
def to_i
3
end
def to_int
5
end
end
Желая явно преобразовать объект класса MyClass
в целое число, мы вызовем метод to_i
:
m = MyClass.new x = m.to_i # 3
Но при передаче объекта MyClass
какой-нибудь функции, ожидающей целое число, будет неявно вызван метод to_int
. Предположим, к примеру, что мы хотим создать массив с известным начальным числом элементов. Метод Array.new
может принять целое, но что если вместо этого ему будет передан объект MyClass
?
m = MyClass.new
a = Array.new(m) # [nil,nil,nil,nil,nil]
Как видите, метод new
оказался достаточно «умным», чтобы вызвать to_int
и затем создать массив из пяти элементов.
Дополнительную информацию о поведении в другом контексте (строковом) вы найдете в разделе 2.16. См. также раздел 5.16.
5.16. Приведение числовых значений
Приведение можно считать еще одним видом неявного преобразования. Если некоторому методу (например, +
) передается аргумент, которого он не понимает, он пытается привести объект, от имени которого вызван, и аргумент к совместимым типам, а затем сложить их. Принцип использования метода coerce в вашем собственном классе понятен из следующего примера:
Интервал:
Закладка: