21 июня 2007 в 14:23

Ruby-фишки

Ruby*
Вижу, многих заинтересовала тема Ruby. И многие просят больше практики и больше кода. Я решил вложить свои 5 копеек :) Не буду писать много теории, а лишь покажу несколько интересных фишек Ruby. Ведь главное в Ruby — красота.

1. Присвоение значений для переменных.
Вот так можно в одну строчку записать присвоение значений нескольким переменным.
x, y, z = 1, 2, 3

Результат: x = 1, y = 2, z = 3


2. Обмен значениями переменных.
Чтобы произвести обмен значениями двух переменных, часто используется третья (z), которая должна временно хранить значения x. В Ruby можно сделать проще:
x, y = 1, 2
x, y = y, x

Результат: x = 2, y = 1

3. Если все аргументы арифметического выражения целые числа, то результат будет целым, если хотя бы одно — число с плавающей точкой, то результат будет с плавающей точкой.
Не совсем очевидный ход и, если не знать о нем, могут возникнуть ошибки. Так, в результате выражения 1/2, вы расчитываете получить 0.5, но Ruby выдаст 0. То есть округлит результат в меньшую сторону до целого.
1/2 #=> 0
3/2 #=> 1

Чтобы получить правильные результаты, нужно чтоб хотя бы одно из чисел было дробным:
1.0/2 #=> 0.5
3.0/2 #=> 1.5

Еще примеры с другими арифметическими операциями:
10 — 5.0 #=> 5.0
8 + 2.0 #=> 10.0
2 * 5.0 #=> 10.0


4. Работа со строками как с массивами
Рассмотрим на простом примере:
str = «Xabrahabr!» # Что-то не так, верно?
str[0] = «H» # Исправим ошибку
puts str #=> Habrahabr!

И получим правильный результат!

5. Отрицательная индексация в массивах.
Как получить последний элемент массива, если длина неизвестна? array[array.length-1]? А предпоследний? array[array.length-2]? В Ruby есть решение лучше!
arr = [1, 2, 3, 4]
arr[-1] #=> 4

Вместе с традиционной положительной индексацией массива, в Ruby существует отрицательная. Самый последний элемент имеет индекс -1, предпоследний -2 и так далее. Запомнить просто: arr[-1] это то же самое, что и arr[arr.length-1], но с без arr.length :)

6. Массив пуст?
Есть множество способов узнать, пуст ли массив. Но самым логичным и простым является логический метод .empty?
arr = []
arr.empty? #=> true


Это далеко не все интересные фишки Ruby. Больше вы можете найти в Викиучебнике и блогах, посвященных языку. Изучайте Ruby и делитесь интересными открытиями с другими.

При подготовке статьи использованы материалы Викиучебника
+2
12
Bright 36,4

комментарии (30)

0
0xa8, #
А теперь, не запуская интерпретатор Ruby, скажите, чему будут равны x,y,z?


x,y,z=1,10,100
x,y,z=y+z,x+z,x+y


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

Да, спецификаций на Ruby нет, поэтому может быть как угодно. Как Матцумото в последней версии интерпретатора напишет, так и будет...

У меня вот вышло => [110, 101, 11], а можно было бы ждать и [110, 210, 320]... От лукавого такой синтаксис.
0
Stranger, #
судя по п.2 будет [110, 101, 11], т.к. это усложненный вариант обмена значениями
+1
xa4a, #
Странно, как можно было ждать [110, 210, 320]? Ведь, насколько я знаю, в большинстве языков программирования оператор присваивания сначала выполняет выражение, находящееся справа от него, тоесть считает [y+z,x+z,x+y], не изменяя самих значений, следовательно результат [110, 101, 11] вполне очевиден.
0
bendingunit22, #
Для правильного ответа достаточно знать приоритет всех операторов.
0
Bright, #
Правильный ответ [110, 101, 11]. Я в уме посчитал, без интерпритатора, как и просили. На мой мозг спецификации тоже нигде нет, но ждать от него других результатов было бы глупо, как и ждать других результатов от Ruby :)
0
Bright, #
>не такая уж и красота
Согласитесь, любую красивую вещь можно превратить в некрасивую. И сделать это довольно просто. Вот пример:
Попробуйте без интерпретатора отгадать, что делает эта конструкция:
(1...10).to_a.sort_by{rand}.to_s.to_i
И запишите эквивалентную ей :)
0
rouss, #
rand(999999999)
0
Bright, #
rand(1000000000)
+1
rouss, #
на самом деле, ни я, ни вы не правы: в рандомном числе могут содержаться повторяющиеся числа, а в той конструкции — нет
0
Bright, #
Вы правы.
Хм, тогда аналогичной конструкции нет...
0
greck, #
Multiple assignement есть в Perl, Python, Lua, Magma,…

Он был придуман давно и отчасти для того, чтобы делать a, b = b, a. Поэтому сомнений насчет логики выполнения здесь быть не может.

Для этой конструкции все уже описано и обсуждено. В Ruby сделано так, как все давно уже привыкли — сначала целиком вычисляется правая часть, потом все присваивается левой. Не Matz это придумал и не ему менять логику multiple assignement.
+1
glader, #
Ну один в один питон :D
0
Bright, #
Не совсем. 4 не сработало. Доступ к элементам строки, как к элементам массива есть, но элементы изменять нельзя.
А есть ли в Питоне способ проверки пуст ли массив, подобный 6?
Мне нравится Питон, но отсутствие фигурных скобок {} и использование отступов для выделения блоков я считаю странностью.
+1
glader, #
Да, строки в питоне неизменяемые.
Да, например можно унаследовать стандартный массив, добавив такой метод.
Я долго писал на перле, теперь - на питоне, и вот, возвращаясь на перл, остро ощущаю избыточность всяких фигурных и простых скобок :)
0
nuclon, #
та же фигня. :)

...Есть ли смысл после Питона изучать Руби? Спрашиваю без желаний запустить холивар, действительно интересно
0
glader, #
Я руби не знаю, но если верно то, что говорят "руби вырос из перла", то думаю, это два эквивалентных языка. И тут уже вопрос личных предпочтений. Попробуй, попытка не пытка :)
0
rouss, #
нет, наверное неправильно говорить, что руби вырос из перла. стоит почитать The Ruby Way, там есть глава о сравнении этих двух языков.
0
Bright, #
Просто попробуйте.
Эти языки во многом схожи.
Часто в сравнении с питоном за руби приводят довод, что это "Чистый ООП язык".
В чем руби откровенно уступает - это в "обеспеченности". Пока нет большого коммьюнити, развитых библиотек и большого количества информации о языке. Мало "живых" примеров.
Но все это со временем появится.
0
isabanin, #
Давно уже всё есть
0
Bright, #
ммм... а есть форум?
я знаю только раздел на форуме vingrad
0
Bregor, #
Ruby очень похож на питон в плане синтаксиса.
Python:
  def returner(value)
    return value

Ruby:
  def returner(value)
    value
  end

Похоже в целом, только в Руби блоки явно заканчиваются кейвордом "end".
Но в руби зато нет жутких питоновских historical reason'ов типа:
something.___do_domeshing___
и почему удаление элемента хэша это del hash[key] а не hash.del(key)? (эту строчку у Юлика (http://live.julik.nl/2005/11/php-is-so-90s) взял).

Без холиваров - я считаю - изучать Руби стоит.
0
Akademic, #
Как-то раз мне захотелось посмотреть на руби.
Посмотрел ролик про RoR - не особенно впечатлило.
А когда попытался узнать, чем же он всем так понравился, в основном натыкался на описание такого вот "синтаксического сахара".
0
green_mouse, #
Ну что я могу вам ответить - каждому своё (холи-варами занимается я не буду). Но скажу вам честно 2 года назад попробовал руби, и до сих пор не могу оторваться. Что привлекает - руби позволяет писать очень понятный код, ну и конечно открытость классов и прочие вкусности. RoR - очень нравится продуманность фреймворка, да иногда приходится лезть в самые его кишки (а в каком фреймворке не надо?), НО в отличие от многих других связка руби + рельсы позволяют сделать это наименее безболезненно (без правки кода рельс).
0
Power, #
Числа из пункта 3 работают так же и в C, и в Java (это к тому, что не так уж это и неожиданно). Кстати, числа - они не дробные, они с плавающей точкой.
0
Shchvova, #
А почему было не запостить этот чудесный пост в блог Rubi?
0
Bright, #
Карма... ((
Я даже комментировать сейчас нормально не могу...
+8
altmind, #
Хороший материал, однако, думаю что на http://pleac.sourceforge.net/ поболей фич различных языков показано.
0
SpeCT, #
Ох, огромное Вам спасибо. Это именна та ссылка, которая мне нужна. Если б мог, поставил бы плюсик :) А пока, ещё раз: большущее спасибище Вам!
0
Bright, #
Хороший сайт, я про него совсем забыл.
Теперь, когда я могу голосовать за комментарии, с радостью ставлю вам плюс!
0
nuclon, #
отличнейшая ссылка, спасибо. занес в букмарки.

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

Миникомпьютер из роутера с OpenWRT: пишем USB class-driver под Linux
Конкурс уязвимостей, или Ломай меня полностью!
Dell Latitude 10: планшет, заменяющий ноутбук