Programming Ruby - Ruby.new, часть 1

Занялся изучением языка ruby и буду по ходу записывать наиболее важные и интересные моменты. И кое-где будут мои комментарии с позиций многолетнего опыта программирования на php.

Начнем с того, что ruby это полностью объектно-ориентированный язык. Это значит что все в нем является объектом, даже числа и строки. Например, вот как можно округлить число:

n = 5.0 / 3.0  
# округлить до целого
puts n.round  
# округлить до двух знаков после запятой
puts m.round(2)  

Что еще можно увидеть на этом примере: функция puts выводит переданные ей аргументы на экран консоли и добавляет после каждого перевод строки. Функцию можно вызывать без указания скобок, но лучше с этим не злоупотреблять. Так например, если во втором случае опустить скобки при вызове метода round уже будет не так просто заметить кому какой аргумент передается, а в более сложных случаях начнутся неоднозначности и ошибки. Так что лучше взять за правило опускать скобки только в самых простых случаях, когда это не мешает читать код. В конце строк не нужно ставить точки с запятой. Мелочь, а приятно :) Для комментирования используется символ #.

Объявить новую функцию просто:

def say_hello(name)  
  result = "Hello, " + name
  return result
end

puts say_hello("Bob")  

Как видите достаточно указать ключевое слово def и имя функции. Конец функции обозначен словом end, фигурные скобки не используются. Если функция не имеет аргументов, то круглые скобки после имени можно не писать. Для отступов в ruby сообществе принято использовать два пробела.

Эту же функцию можно переписать немного по другому:

def say_hello(name)  
  "Hello, #{name}"
end  

Во-первых, писать слово return не обязательно, функция всегда возвращает результат последнего выражения. Во-вторых, можно использовать подстановку выражений в строках. В отличии от php здесь можно использовать любые выражения:

puts "2 + 3 = #{2 + 3}"  

Так же как и в php такие подстановки вычисляются только для строк в двойных кавычках.

И пара слов о стандартах именования. Переменные и функции принято называть с маленькой буквы, а слова в названии разделять символом подчеркивания. В названии классов наоборот, все слова с большой буквы, символ подчеркивания не используется. Названия чувствительны к регистру букв.

Массивы и хеши

Массивы и хеши в руби это индексированные коллекции, доступ к значениям которых осуществляется по ключу. В качестве значений могут быть объекты любых типов, в одной коллекции могут быть значения разных типов. У массива ключами всегда являются целые числа, у хешей ключом может любой объект. И массивы и хеши не имеют фиксированного размера и при добавлении нового элемента увеличиваются в размере. Доступ к элементам массива более эффективный, зато хеши предоставляют больше гибкости.

Пример объявления массива:

a1 = [1, 'cat', 3.14]  

Если массив будет содержать только строки, то можно использовать более удобную запись:

a2 = %w{one two three} # => ['one', 'two', 'three']  

Пример объявления хеша:

h = {  
  'key1' => 'value1',
  'key2' => 'value2'
}

У хешей есть возможность изменять значение для несуществующего ключа. По дефолту возвращается nil:

h1 = {}  
puts h1['qwe'] # => nil  
h2 = Hash.new(0)  
puts h2['qwe'] # => 0  

В руби есть такие интересные объекты, которые называются символы (symbols). Что такое символы объяснить не так просто. Попробую на примере констант в пхп (или любом другом языке). Если вы объявили контанту, то потом можете использовать её в любом месте программы. Например:

define('NORTH', 'north');  
// ...
if ($param == NORTH) {  
 // ...
}

А теперь представьте что вам не нужно заранее объявлять контанту:

if param == :north  
  # ...
end  

Таким образом даже если в коде у вас символ :north будет встречаться хоть тысячу раз, в памяти им будет соответствовать только один объект символа. Поэтому везде где вам нужно использовать строки для в качестве каки-то флагов или для подобных целей, то лучше использовать символы - это и удобнее и эффективнее.

Очень часто символы используют в качестве ключей хеша:

h = {  
 :key1 => 'value1',
 :key2 => 'value2'
}
puts h[:key1] # => value1  

Cимволы в качестве ключей хеша используют настолько часто, что в последних версиях руби для этого даже ввели специальный синтаксис:

h = {  
  key1: 'value1',
  key2: 'value2'
}