Офіційний FAQ Ruby
+ +--- + +{% include faq-notice.md %} + +## Ітератори + +### Що таке ітератор? + +Ітератор — це метод, який приймає блок або об’єкт `Proc`. У вихідному +файлі блок розташовується одразу після виклику методу. Ітератори +використовуються для створення користувацьких керувальних структур — +особливо циклів. + +Розгляньмо приклад, щоб побачити, як це працює. Ітератори часто +використовуються для повторення тієї самої дії над кожним елементом +колекції, наприклад так: + +~~~ +data = [1, 2, 3] +data.each do |i| + puts i +end +~~~ + +Виведе: + +~~~ +1 +2 +3 +~~~ + +Методу `each` масиву `data` передається блок `do ... end`, і він +виконується багато разів. При кожному виклику блоку передається +черговий елемент масиву. + +Ви можете визначати блоки за допомогою `{ ... }` замість `do ... end`. + +~~~ +data = [1, 2, 3] +data.each { |i| + puts i +} +~~~ + +Виведе: + +~~~ +1 +2 +3 +~~~ + +Цей код має те саме значення, що й попередній приклад. Однак у деяких +випадках питання пріоритетів робить `do ... end` і `{ ... }` різними. + +~~~ +foobar a, b do ... end # foobar is the iterator. +foobar a, b { ... } # b is the iterator. +~~~ + +Це тому, що `{ ... }` прив’язується до попереднього виразу сильніше, +ніж блок `do ... end`. Перший приклад еквівалентний +`foobar(a, b) do ... end`, тоді як другий — `foobar(a, b { ... })`. + +### Як передати блок до ітератора? + +Просто розмістіть блок після виклику ітератора. Ви також можете +передати об’єкт `Proc`, додавши `&` перед іменем змінної або константи, +що посилається на `Proc`. + +### Як використовується блок в ітераторі? + +{% include warnings/faq-out-of-date.html %} + +Є три способи виконати блок з методу-ітератора: +(1) керувальна структура `yield`; (2) виклик аргументу `Proc` +(створеного з блоку) через `call`; (3) використання `Proc.new`, +після якого слідує виклик. + +Оператор `yield` викликає блок, за потреби передаючи один або більше +аргументів. + +~~~ +def my_iterator + yield 1, 2 +end + +my_iterator {|a, b| puts a, b } +~~~ + +Виведе: + +~~~ +1 +2 +~~~ + +Якщо визначення методу має аргумент блоку (останній формальний параметр +має префікс амперсанда `&`), він отримає приєднаний блок, перетворений +на об’єкт `Proc`. Його можна викликати через `prc.call(args)`. + +~~~ +def my_iterator(&b) + b.call(1, 2) +end + +my_iterator {|a, b| puts a, b } +~~~ + +Виведе: + +~~~ +1 +2 +~~~ + +`Proc.new` (або еквівалентні виклики `proc` чи `lambda`), коли +використовується у визначенні ітератора, бере блок, переданий у метод, +і створює з нього процедурний об’єкт. +(`proc` і `lambda` фактично є синонімами.) + +_[Потрібне оновлення: `lambda` поводиться трохи інакше і +генерує попередження `tried to create Proc object without a block`.]_ + +~~~ +def my_iterator + Proc.new.call(3, 4) + proc.call(5, 6) + lambda.call(7, 8) +end + +my_iterator {|a, b| puts a, b } +~~~ + +Виведе: + +~~~ +3 +4 +5 +6 +7 +8 +~~~ + +Можливо, несподівано, `Proc.new` і подібні методи жодним чином не +“споживають” блок, прикріплений до методу — кожен виклик `Proc.new` +створює новий процедурний об’єкт з того самого блоку. + +Ви можете дізнатися, чи є блок, пов’язаний із методом, викликавши +`block_given?`. + +### Що робить `Proc.new` без блоку? + +`Proc.new` без блоку не може створити процедурний об’єкт і викликає помилку. +Проте у визначенні методу `Proc.new` без блоку припускає наявність блоку +на момент виклику методу, тож помилки не буде. + +### Як запускати ітератори паралельно? + +Ось адаптація рішення від Matz, із +[\[ruby-talk:5252\]][ruby-talk:5252], що використовує потоки: + +~~~ +require "thread" + +def combine(*iterators) + queues = [] + threads = [] + + iterators.each do |it| + queue = SizedQueue.new(1) + th = Thread.new(it, queue) do |i, q| + send(i) {|x| q << x } + end + queues << queue + threads << th + end + + loop do + ary = [] + queues.each {|q| ary << q.pop } + yield ary + + iterators.size.times do |i| + return if !threads[i].status && queues[i].empty? + end + end +end + +def it1 + yield 1; yield 2; yield 3 +end + +def it2 + yield 4; yield 5; yield 6 +end + +combine(:it1, :it2) do |x| + # x is [1, 4], then [2, 5], then [3, 6] +end +~~~ + +[ruby-talk:5252]: https://blade.ruby-lang.org/ruby-talk/5252 diff --git a/ua/documentation/faq/6/index.md b/ua/documentation/faq/6/index.md new file mode 100644 index 0000000000..47233a11e0 --- /dev/null +++ b/ua/documentation/faq/6/index.md @@ -0,0 +1,294 @@ +--- +layout: page +title: "Офіційний FAQ Ruby" +lang: ua + +header: | + +Офіційний FAQ Ruby
+ +--- + +{% include faq-notice.md %} + +## Синтаксис + +### У чому різниця між безпосереднім значенням і посиланням? +{: #immediate} + +{% include warnings/faq-out-of-date.html %} + +`Fixnum`, `true`, `nil` і `false` реалізовані як безпосередні значення. +Для безпосередніх значень змінні зберігають самі об’єкти, а не +посилання на них. + +Для таких об’єктів не можна визначати singleton-методи. Два `Fixnum` +з однаковим значенням завжди представляють той самий екземпляр об’єкта, +тому (наприклад) змінні екземпляра для `Fixnum` зі значенням `1` +спільні для всіх `1` у системі. Це робить неможливим визначення +singleton-методу лише для одного з них. + +### У чому різниця між `nil` і `false`? + +Спочатку про схожість: `nil` і `false` — єдині два об’єкти, +які в булевому контексті оцінюються як `false`. +(Інакше кажучи: це єдині «falsy»-значення, усі інші +об’єкти — «truthy».) + +Однак `nil` і `false` — це екземпляри різних класів +(`NilClass` і `FalseClass`) і в інших місцях поводяться по-різному. + +Ми рекомендуємо, щоб предикатні методи (ті, чия назва закінчується знаком +питання) повертали `true` або `false`. Інші методи, яким потрібно +позначити невдачу, мають повертати `nil`. + +### Чому порожній рядок не є `false`? + +П: Порожній рядок (`""`) повертає `true` в умовному виразі! +У Perl це `false`. + +В: Але Ruby — не Perl ;-). Все дуже просто: у Ruby лише `nil` +і `false` є хибними в умовних контекстах. + +Можна використати `empty?`, порівняти рядок із `""` або порівняти його +`size` чи `length` із `0`, щоб дізнатися, чи рядок порожній. + +### Що означає `:name`? + +Двокрапка перед іменем створює об’єкт Symbol, який однозначно відповідає +ідентифікатору. Протягом виконання програми для певного імені або рядка +буде створено той самий об’єкт Symbol. Символи також можна створити +за допомогою `"name".intern` або `"name".to_sym`. + +Об’єкти Symbol можуть представляти ідентифікатори методів, змінних тощо. +Деякі методи, такі як `define_method`, `method_missing` або `trace_var`, +потребують символ. Інші методи, наприклад `attr_accessor`, `send` +або `autoload`, також приймають рядок. + +Оскільки вони створюються лише один раз, символи часто використовують як +ключі хешів. Рядкові ключі хешів створювали б новий об’єкт для кожного +використання, спричиняючи певні витрати пам’яті. +Є навіть спеціальний синтаксис для ключів-символів: + +~~~ +person_1 = { :name => "John", :age => 42 } +person_2 = { name: "Jane", age: 24 } # alternate syntax +~~~ + +Символи також можна використовувати як значення переліків +або для присвоєння унікальних значень константам: + +~~~ +status = :open # :closed, ... + +NORTH = :NORTH +SOUTH = :SOUTH +~~~ + +### Як отримати значення символу? + +Щоб отримати значення змінної, що відповідає символу, можна використати +`symbol.to_s` або `"#{symbol}"`, щоб отримати ім’я змінної, а потім +виконати це через `eval` у відповідній області видимості й отримати +вміст змінної: + +~~~ +a = "This is the content of `a'" +b = eval("#{:a}") +a.object_id == b.object_id # => true +~~~ + +Також можна використати + +~~~ +b = binding.local_variable_get(:a) +~~~ + +Якщо ваш символ відповідає імені методу, можна використати `send`: + +~~~ +class Demo + def hello + "Hello, world" + end +end + +demo = Demo.new +demo.send(:hello) +~~~ + +Або можна використати `Object#method`, щоб повернути відповідний об’єкт +`Method`, який потім можна викликати: + +~~~ +m = demo.method(:hello) # => #Офіційний FAQ Ruby
+ +--- + +{% include faq-notice.md %} + +## Методи + +### Як Ruby вибирає, який метод викликати? + +Ruby динамічно прив’язує всі повідомлення до методів. Спершу він шукає +singleton-методи в отримувачі, потім методи, визначені у власному класі +отримувача, і нарешті методи, визначені в суперкласах отримувача +(включно з будь-якими модулями, які могли бути домішані). Порядок пошуку +можна побачити, вивівши `ClassName.ancestors`, який показує класи-предки +та модулі `ClassName`. + +Якщо після пошуку серед альтернатив відповідний метод не знайдено, +Ruby намагається викликати метод `method_missing`, повторюючи ту саму +процедуру пошуку для нього. Це дає змогу обробляти повідомлення +до невідомих методів і часто використовується для надання динамічних +інтерфейсів класам. + +~~~ +module Emphasizable + def emphasize + "**#{self}**" + end +end + +class String + include Emphasizable +end + +String.ancestors + # => [String, Emphasizable, Comparable, Object, Kernel, BasicObject] + +"Wow!".emphasize # => "**Wow!**" +~~~ + +Коли під час пошуку методу `emphasize` його не знаходять у класі `String`, +Ruby далі шукає в модулі `Emphasizable`. + +Щоб перевизначити метод, який уже існує в класі отримувача, +наприклад `String#capitalize`, потрібно вставити модуль у ланцюжок +предків перед цим класом, використавши `prepend`: + +~~~ +module PrettyCapitalize + def capitalize + "**#{super}**" + end +end + +class String + prepend PrettyCapitalize +end + +String.ancestors + # => [PrettyCapitalize, String, Comparable, Object, Kernel, BasicObject] + +"hello".capitalize # => "**Hello**" +~~~ + +### Чи є `+`, `-`, `*`, ... операторами? + +`+`, `-` та подібні — це не оператори, а виклики методів. +Тому їх можна перевантажувати новими визначеннями. + +~~~ +class MyString < String + def -(other) + self[0...other.size] # self truncated to other's size + end +end +~~~ + +Однак наведені нижче — вбудовані керувальні структури, а не методи, +тому їх не можна перевизначити: + +~~~ +=, .., ..., not, ||, &&, and, or, :: +~~~ + +Щоб перевантажити або визначити унарні оператори `+` і `-`, +потрібно використовувати `+@` і `-@` як назви методів. + +Оператор `=` використовується для визначення методу, що встановлює +атрибут об’єкта: + +~~~ +class Test + def attribute=(val) + @attribute = val + end +end + +t = Test.new +t.attribute = 1 +~~~ + +Якщо визначені оператори на кшталт `+` і `-`, Ruby автоматично обробляє +форми самоприсвоєння (`+=`, `-=` тощо). + +### Де `++` і `--`? + +У Ruby немає операторів автоінкременту та автодекременту. +Замість них можна використати `+= 1` і `-= 1`. + +### Що таке singleton-метод? +{: #singleton-method} + +Singleton-метод — це метод екземпляра, пов’язаний з одним конкретним +об’єктом. + +Singleton-метод створюють, включаючи об’єкт у визначення: + +~~~ +class Foo; end + +foo = Foo.new +bar = Foo.new + +def foo.hello + puts "Hello" +end + +foo.hello +bar.hello +~~~ + +Виведе: + +~~~ +Hello +prog.rb:11:in `Офіційний FAQ Ruby
+ +--- + +{% include faq-notice.md %} + +## Класи та модулі + +### Чи можна повторно визначати клас? + +Клас можна визначати повторно. Кожне визначення додається до +попереднього. Якщо метод перевизначено, попередній перевизначається +і втрачається. + +### Чи існують змінні класу? + +Так. Змінна з двома знаками `@` (`@@`) — це змінна класу, доступна як у +методах екземпляра, так і в методах класу. + +~~~ +class Entity + + @@instances = 0 + + def initialize + @@instances += 1 + @number = @@instances + end + + def who_am_i + "I'm #{@number} of #{@@instances}" + end + + def self.total + @@instances + end +end + +entities = Array.new(9) { Entity.new } + +entities[6].who_am_i # => "I'm 7 of 9" +Entity.total # => 9 +~~~ + +Однак, найімовірніше, варто використовувати _змінні екземпляра класу_. + +### Що таке змінна екземпляра класу? + +Ось приклад із попереднього розділу, переписаний із використанням змінної +екземпляра класу: + +~~~ +class Entity + + @instances = 0 + + class << self + attr_accessor :instances # provide class methods for reading/writing + end + + def initialize + self.class.instances += 1 + @number = self.class.instances + end + + def who_am_i + "I'm #{@number} of #{self.class.instances}" + end + + def self.total + @instances + end +end + +entities = Array.new(9) { Entity.new } + +entities[6].who_am_i # => "I'm 7 of 9" +Entity.instances # => 9 +Entity.total # => 9 +~~~ + +Тут `@instances` — це _змінна екземпляра_ класу. Вона не належить +екземпляру класу `Entity`, а належить об’єкту класу `Entity`, який є +екземпляром класу `Class`. + +Змінні екземпляра класу безпосередньо доступні лише в методах класу. + +### У чому різниця між змінними класу та змінними екземпляра класу? + +Головна різниця — у поведінці щодо наслідування: змінні класу спільні для +класу та всіх його підкласів, тоді як змінні екземпляра класу належать +лише одному конкретному класу. + +Змінні класу певною мірою можна розглядати як глобальні змінні в контексті +ієрархії наслідування, з усіма проблемами, притаманними глобальним змінним. +Наприклад, змінна класу може (випадково) бути переприсвоєна будь-яким із +підкласів, що вплине на всі інші класи: + +~~~ +class Woof + + @@sound = "woof" + + def self.sound + @@sound + end +end + +Woof.sound # => "woof" + +class LoudWoof < Woof + @@sound = "WOOF" +end + +LoudWoof.sound # => "WOOF" +Woof.sound # => "WOOF" (!) +~~~ + +Або клас-предка можуть згодом повторно відкрити й змінити, що може мати +несподівані наслідки: + +~~~ +class Foo + + @@var = "foo" + + def self.var + @@var + end +end + +Foo.var # => "foo" (as expected) + +class Object + @@var = "object" +end + +Foo.var # => "object" (!) +~~~ + +Тож якщо ви точно не знаєте, що робите, і вам справді не потрібна така +поведінка, краще використовуйте змінні екземпляра класу. + +### Чи має Ruby методи класу? +{: #class-method} + +Singleton-метод об’єкта класу називається методом класу. +(Насправді метод класу визначається в метакласі, але це здебільшого +прозоро). Інакше кажучи, метод класу — це метод, отримувачем якого є клас. + +Зводиться все до того, що методи класу можна викликати без екземплярів +цього класу (об’єктів) як отримувача. + +Створімо singleton-метод класу `Foo`: + +~~~ +class Foo + def self.test + "this is foo" + end +end + +# It is invoked this way. + +Foo.test # => "this is foo" +~~~ + +У цьому прикладі `Foo.test` — метод класу. + +Методи екземпляра, визначені в класі `Class`, можна використовувати як +методи класу для кожного(!) класу. + +### Що таке singleton-клас? + +Singleton-клас — це анонімний клас, створений шляхом наслідування класу, +пов’язаного з конкретним об’єктом. Singleton-класи — ще один спосіб +розширити функціональність, пов’язану лише з одним об’єктом. + +Візьмімо скромний `Foo`: + +~~~ +class Foo + def hello + "hello" + end +end + +foo = Foo.new +foo.hello # => "hello" +~~~ + +А тепер уявімо, що потрібно додати функціональність рівня класу лише для +цього одного екземпляра: + +~~~ +class << foo + attr_accessor :name + + def hello + "hello, I'm #{name}" + end +end + +foo.name = "Tom" +foo.hello # => "hello, I'm Tom" +Foo.new.hello # => "hello" +~~~ + +Ми налаштували `foo`, не змінюючи характеристики `Foo`. + +### Що таке функція модуля? + +{% include warnings/faq-out-of-date.html %} + +Функція модуля — це приватний singleton-метод, визначений у модулі. +По суті, це схоже на [метод класу](#class-method), оскільки його можна +викликати у вигляді `Module.method`: + +~~~ +Math.sqrt(2) # => 1.414213562 +~~~ + +Проте, оскільки модулі можна домішувати до класів, функції модуля можна +використовувати і без префікса (саме так функції `Kernel` стають +доступними об’єктам): + +~~~ +include Math +sqrt(2) # => 1.414213562 +~~~ + +Використайте `module_function`, щоб зробити метод функцією модуля. + +~~~ +module Test + def thing + # ... + end + module_function :thing +end +~~~ + +### У чому різниця між класом і модулем? + +Модулі — це колекції методів і констант. Вони не можуть створювати +екземпляри. Класи можуть створювати екземпляри (об’єкти) і мають стан на +рівні екземпляра (змінні екземпляра). + +Модулі можна домішувати до класів і інших модулів. Константи й методи +домішаного модуля змішуються з власними константами й методами класу, +розширюючи його функціональність. Натомість класи не можна домішувати +ні до чого. + +Клас може успадковувати інший клас, але не модуль. + +Модуль не може наслідувати нічого. + +### Чи можна успадковувати модулі? + +Ні. Однак модуль можна включити до класу або іншого модуля, щоб імітувати +множинне наслідування (механізм mixin). + +Це не створює підклас (для цього потрібне наслідування), але створює +зв’язок `is_a?` між класом і модулем. + +### Наведіть приклад mixin + +Модуль `Comparable` надає різноманітні оператори порівняння +(`<`, `<=`, `==`, `>=`, `>`, `between?`). Він визначає їх через виклики +загального методу порівняння `<=>`. Однак сам `<=>` він не визначає. + +Припустімо, ви хочете створити клас, у якому порівняння ґрунтуються на +кількості ніг тварини: + +~~~ +class Animal + include Comparable + + attr_reader :legs + + def initialize(name, legs) + @name, @legs = name, legs + end + + def <=>(other) + legs <=> other.legs + end + + def inspect + @name + end +end + +c = Animal.new("cat", 4) +s = Animal.new("snake", 0) +p = Animal.new("parrot", 2) + +c < s # => false +s < c # => true +p >= s # => true +p.between?(s, c) # => true +[p, s, c].sort # => [snake, parrot, cat] +~~~ + +Все, що потрібно `Animal`, — визначити власну семантику оператора `<=>` +і домішати модуль `Comparable`. Методи `Comparable` стають +невідрізненними від методів `Animal`, і ваш клас раптово отримує нову +функціональність. А оскільки той самий модуль `Comparable` використовують +багато класів, ваш новий клас матиме узгоджену й добре зрозумілу семантику. + +### Чому існує два способи визначення методів класу? + +Метод класу можна визначити всередині визначення класу, а також на +верхньому рівні. + +~~~ +class Demo + def self.class_method + end +end + +def Demo.another_class_method +end +~~~ + +Між ними є лише одна суттєва різниця. У визначенні класу можна звертатися +до констант класу безпосередньо, оскільки вони в області видимості. +На верхньому рівні потрібно використовувати нотацію `Class::CONST`. + +### У чому різниця між `include` і `extend`? + +{% include warnings/faq-out-of-date.html %} + +`include` домішує модуль до класу або іншого модуля. Методи з цього +модуля викликаються у функціональному стилі (без отримувача). + +`extend` використовується, щоб включити модуль в об’єкт (екземпляр). +Методи модуля стають методами об’єкта. + +### Що означає `self`? + +`self` — це поточний отримувач виконання, об’єкт, до якого +застосовується метод. Виклик методу у функціональному стилі +передбачає `self` як отримувача. diff --git a/ua/documentation/faq/9/index.md b/ua/documentation/faq/9/index.md new file mode 100644 index 0000000000..f9f08a27a0 --- /dev/null +++ b/ua/documentation/faq/9/index.md @@ -0,0 +1,376 @@ +--- +layout: page +title: "Офіційний FAQ Ruby" +lang: ua + +header: | + +Офіційний FAQ Ruby
+ +--- + +{% include faq-notice.md %} + +## Вбудовані бібліотеки + +### Що повертає `instance_methods(false)`? + +Метод `instance_methods` повертає масив із назвами методів екземпляра +в класі або модулі-отримувачі. Це включає методи суперкласів і +домішаних модулів. + +`instance_methods(false)` або `instance_methods(nil)` повертає назви +лише тих методів, що визначені в отримувачі. + +### Як працюють зерна генератора випадкових чисел? + +Якщо `rand` викликається без попереднього виклику `srand`, генератор +псевдовипадкових чисел Ruby використовує довільне (майже випадкове) +зерно, яке, серед іншого, бере ентропію з джерела ОС, якщо воно доступне. +Послідовні запуски програми, що не використовує `srand`, генеруватимуть +різні послідовності випадкових чисел. + +Для тестування можна отримати передбачувану поведінку з однаковою +послідовністю чисел при кожному запуску, викликавши `srand` із +фіксованим зерном. + +### Я прочитав файл і змінив його, але файл на диску не змінився. + +~~~ +File.open("example", "r+").readlines.each_with_index do |line, i| + line[0,0] = "#{i+1}: " +end +~~~ + +Ця програма _не_ додає номери рядків до файла `example`. Вона читає +вміст файла і для кожного рядка додає номер на початку, але дані +ніколи не записуються назад. Наведений нижче код _дійсно_ оновлює +файл (хоча це дещо небезпечно, бо перед оновленням не створюється +резервна копія): + +~~~ +File.open("example", "r+") do |f| + lines = f.readlines + lines.each_with_index {|line, i| line[0,0] = "#{i+1}: " } + f.rewind + f.puts lines +end +~~~ + +### Як опрацювати файл і оновити його вміст? + +Використовуючи параметр командного рядка `-i` або вбудовану змінну `$-i`, +можна читати файл і замінювати його. + +Код із попереднього запитання, який додавав номери рядків до файла, +найкраще записати цим способом: + +~~~ +$ ruby -i -ne 'print "#$.: #$_"' example +~~~ + +Якщо потрібно зберегти оригінальний файл, використайте `-i.bak`, щоб +створити резервну копію. + +### Я записав файл, скопіював його, але кінець копії ніби втрачено. + +Цей код працюватиме неправильно: + +~~~ +require "fileutils" + +File.open("file", "w").puts "This is a file." +FileUtils.cp("file", "newfile") +~~~ + +Оскільки введення/виведення буферизується, `file` копіюється до того, як +його вміст записано на диск. `newfile`, імовірно, буде порожнім. Однак +коли програма завершується, буфери скидаються, і `file` має очікуваний +вміст. + +Проблеми не буде, якщо переконатися, що `file` закритий перед копіюванням: + +~~~ +require "fileutils" + +File.open("file", "w") {|f| f.puts "This is a file." } +FileUtils.cp("file", "newfile") +~~~ + +### Як отримати номер рядка в поточному вхідному файлі? + +Під час читання з файла Ruby збільшує лічильник рядків у глобальній +змінній `$.`. Це також доступно через атрибут `lineno` об’єкта `File`. + +Спеціальна константа `ARGF` — це об’єкт, схожий на файл, який можна +використовувати для читання всіх вхідних файлів, вказаних у командному +рядку (або стандартного вводу, якщо файлів немає). `ARGF` неявно +використовується в такому коді: + +~~~ +while gets + print $_ +end +~~~ + +У цьому випадку `$.` буде кумулятивною кількістю рядків, прочитаних +у всіх вхідних файлах. Щоб отримати номер рядка в поточному файлі, +використайте + +~~~ +ARGF.file.lineno +~~~ + +Також можна отримати назву поточного файла через `ARGF.file.path`. + +### Як використовувати `less` для показу виводу програми? + +Я спробував таке, але нічого не вивелося: + +~~~ +open("|less", "w").puts "abc" +~~~ + +Це тому, що програма завершується одразу, і `less` не встигає побачити те, +що ви йому записали, не кажучи вже про відображення. Переконайтеся, що +потік правильно закривається, і він чекатиме, доки завершиться `less`. + +~~~ +open("|less", "w") {|f| f.puts "abc" } +~~~ + +### Що відбувається з об’єктом `File`, на який більше ніхто не посилається? + +Об’єкт `File`, на який більше немає посилань, стає придатним для +збирання сміття. Файл буде закрито автоматично, коли об’єкт `File` буде +зібрано. + +### Мені не по собі, якщо я не закриваю файл. + +Є принаймні чотири добрі способи гарантувати, що файл буде закрито: + +~~~ +# (1) +f = File.open("file") +begin + f.each {|line| print line } +ensure + f.close +end + +# (2) +File.open("file") do |f| + f.each {|line| print line } +end + +# (3) +File.foreach("file") {|line| print line } + +# (4) +File.readlines("file").each {|line| print line } +~~~ + +### Як відсортувати файли за часом зміни? + +~~~ +Dir.glob("*").sort {|a, b| File.mtime(b) <=> File.mtime(a) } +~~~ + +Хоча це працює (повертає список у зворотному хронологічному порядку), +це не дуже ефективно, адже під час кожного порівняння отримує час +модифікації файлів з ОС. + +Більшої ефективності можна досягти ціною додаткової складності: + +~~~ +Dir.glob("*").map {|f| [File.mtime(f), f] }. + sort {|a, b| b[0] <=> a[0] }.map(&:last) +~~~ + +### Як порахувати частоту слів у файлі? + +~~~ +freq = Hash.new(0) +File.read("example").scan(/\w+/) {|word| freq[word] += 1 } +freq.keys.sort.each {|word| puts "#{word}: #{freq[word]}" } +~~~ + +Виведе: + +~~~ +and: 1 +is: 3 +line: 3 +one: 1 +this: 3 +three: 1 +two: 1 +~~~ + +### Як відсортувати рядки в алфавітному порядку? + +Якщо ви хочете, щоб рядки сортувалися як 'AAA', 'BBB', ..., 'ZZZ', +'aaa', 'bbb', то вбудоване порівняння працюватиме чудово. + +Якщо потрібно сортувати без урахування регістру, порівнюйте зведені до +нижнього регістру рядки в блоці сортування: + +~~~ +array = %w( z bB Bb bb Aa BB aA AA aa a A ) +array.sort {|a, b| a.downcase <=> b.downcase } + # => ["a", "A", "Aa", "aA", "AA", "aa", "bB", "Bb", "bb", "BB", "z"] +~~~ + +Якщо потрібно сортувати так, щоб 'A' і 'a' йшли поруч, але 'a' вважалася +більшою за 'A' (тобто 'Aa' після 'AA', але перед 'AB'), використайте: + +~~~ +array.sort {|a, b| (a.downcase <=> b.downcase).nonzero? || a <=> b } + # => ["A", "a", "AA", "Aa", "aA", "aa", "BB", "Bb", "bB", "bb", "z"] +~~~ + +### Як перетворити табуляції на пробіли? +{: #tab-expansion} + +Якщо `a` містить рядок, який потрібно розгорнути, можна використати один із: + +~~~ +1 while a.sub!(/(^[^\t]*)\t(\t*)/){$1+" "*(8-$1.size%8+8*$2.size)} +# or +1 while a.sub!(/\t(\t*)/){" "*(8-$~.begin(0)%8+8*$1.size)} +# or +a.gsub!(/([^\t]{8})|([^\t]*)\t/n){[$+].pack("A8")} +~~~ + +### Як екранувати зворотний слеш у регулярному виразі? + +`Regexp.quote('\\')` екранує зворотний слеш. + +Складніше, якщо ви використовуєте `sub` і `gsub`. Скажімо, ви пишете +`gsub(/\\/, '\\\\')`, сподіваючись замінити кожен зворотний слеш двома. +Другий аргумент перетворюється на `'\\'` під час синтаксичного +аналізу. Коли відбувається підстановка, механізм регулярних виразів +перетворює це на `'\'`, тож у підсумку кожен окремий зворотний слеш +замінюється іншим окремим зворотним слешем. Треба писати +`gsub(/\\/, '\\\\\\')`! + +Втім, з урахуванням того, що `\&` містить збіг, можна також написати +`gsub(/\\/, '\&\&')`. + +Якщо ви використовуєте блочну форму `gsub`, тобто +`gsub(/\\/) { '\\\\' }`, рядок для підстановки аналізується лише +один раз (під час синтаксичного проходу) і результат буде таким, як ви +й задумували. + +### У чому різниця між `sub` і `sub!`? + +У `sub` створюється копія отримувача, до неї застосовується заміна, +і вона повертається. + +У `sub!` отримувач змінюється і повертається, якщо знайдено збіг. +Інакше повертається `nil`. + +Методи на кшталт `sub!`, які змінюють стан отримувача, називаються +[деструктивними методами](../7/#destructive-method). +Зазвичай, якщо є два схожі методи і один із них деструктивний, +деструктивний має суфікс `!`. + +~~~ +def foo(str) + str.sub(/foo/, "baz") +end + +obj = "foo" +foo(obj) # => "baz" +obj # => "foo" + +def foo(str) + str.sub!(/foo/, "baz") +end + +foo(obj) # => "baz" +obj # => "baz" +~~~ + +### Де спрацьовує `\Z`? + +`\Z` збігається безпосередньо перед останнім `\n` (переведенням рядка), +якщо рядок закінчується на `\n`, інакше — в кінці рядка. + +### У чому різниця між `thread` і `fork`? + +{% include warnings/faq-out-of-date.html %} + +Потоки Ruby реалізовані всередині інтерпретатора, тоді як `fork` +викликає операційну систему для створення окремого підпроцесу. + +`thread` і `fork` мають такі характеристики: + +* `fork` повільний, `thread` — ні. +* `fork` не розділяє адресний простір пам’яті. +* `thread` не спричиняє thrashing. +* `thread` працює на DOS. +* Коли `thread` потрапляє у взаємне блокування, весь процес зупиняється. +* `fork` може скористатися паузами очікування завершення вводу/виводу, + `thread` — ні (принаймні без додаткової допомоги). + +Ймовірно, не варто змішувати `fork` і `thread`. + +### Як використовувати `Marshal`? + +`Marshal` використовується для збереження об’єкта у файлі або рядку з +подальшим відновленням. Об’єкти можна зберігати так: + +~~~ +Marshal.dump( obj [, io ] [, lev] ) +~~~ + +`io` — записуваний об’єкт `IO`, `lev` задає рівень, до якого об’єкти +дереференціюються і зберігаються. Якщо виконано `lev` рівнів +дереференціювання і все ще існують посилання на об’єкти, тоді `dump` +зберігає лише посилання, а не сам об’єкт. Це погано, бо такі об’єкти +неможливо відновити згодом. + +Якщо `io` пропущено, маршалізовані об’єкти повертаються у вигляді рядка. + +Повернути об’єкти можна так: + +~~~ +obj = Marshal.load(io) +# or +obj = Marshal.load(str) +~~~ + +де `io` — читаний об’єкт `IO`, а `str` — збережений рядок. + +### Як використовувати `trap`? + +`trap` пов’язує блоки коду із зовнішніми подіями (сигналами). + +~~~ +trap("PIPE") { raise "SIGPIPE" } +~~~ diff --git a/ua/documentation/faq/index.md b/ua/documentation/faq/index.md new file mode 100644 index 0000000000..201e3c8361 --- /dev/null +++ b/ua/documentation/faq/index.md @@ -0,0 +1,62 @@ +--- +layout: page +title: "Офіційний FAQ Ruby" +lang: ua + +header: | + +Офіційний FAQ Ruby
+ +--- + +Цей документ містить відповіді на поширені запитання про Ruby. +{: .summary} + +Цей FAQ базується на "[The Ruby Language FAQ][original-faq]", спочатку +скомпільованому Shugo Maeda та перекладеному англійською Kentaro Goto. +Дякуємо Zachary Scott і Marcus Stollsteimer за включення FAQ на сайт +і за суттєве оновлення змісту. + +Приклади коду в цьому документі виконано на Ruby 2.3. + +[original-faq]: http://ruby-doc.org/docs/ruby-doc-bundle/FAQ/FAQ.html + +{% include faq-notice.md %} + +## Зміст + +* [Загальні питання](1/) +* [Як Ruby порівнюється з...?](2/) +* [Встановлення Ruby](3/) +* [Змінні, константи та аргументи](4/) +* [Ітератори](5/) +* [Синтаксис](6/) +* [Методи](7/) +* [Класи та модулі](8/) +* [Вбудовані бібліотеки](9/) +* [Бібліотека розширень](10/) +* [Інші можливості](11/) diff --git a/ua/documentation/index.md b/ua/documentation/index.md new file mode 100644 index 0000000000..d89cf70257 --- /dev/null +++ b/ua/documentation/index.md @@ -0,0 +1,249 @@ +--- +layout: page +title: "Документація" +lang: ua +--- + +Посібники, туторіали та довідкові матеріали, які допоможуть дізнатися більше про Ruby +{: .summary} + +### Встановлення Ruby + +Хоча ви можете легко [спробувати Ruby у браузері][1], ви також можете +переглянути [посібник зі встановлення](installation/), щоб отримати +допомогу зі встановленням Ruby. + +### Офіційна документація Ruby + +[docs.ruby-lang.org/en][docs-rlo]: список документації для всіх версій Ruby, випущених після 2.1. + +[docs.ruby-lang.org/en/3.4][docs-rlo-3.4]: документація для Ruby 3.4. + +[docs.ruby-lang.org/en/master][docs-rlo-master]: документація для гілки master Ruby. + +[Посібник зі створення C-розширень][docs-rlo-extension]: поглиблений посібник зі створення C-розширень для Ruby. + +### Початок роботи + +[Try Ruby][1] +: Ви можете спробувати Ruby прямо у браузері. + +[Learn to Program][8] +: Невеликий чудовий туторіал від Chris Pine для новачків у програмуванні. + Якщо ви не вмієте програмувати, почніть тут. + +[Ruby за двадцять хвилин][rubyin20] +: Невеликий туторіал Ruby, який має зайняти не більше 20 хвилин. + +[The Odin Project][odin] +: Open source навчальна програма з full stack. + +[Exercism][exercism] +: 120 вправ з автоматичною перевіркою та персональним менторингом. + +[Codecademy][codecademy] +: Онлайн bootcamp з кодування з різними темами. + +### Посібники / Книги + +#### Початковий рівень + +[Programming Ruby 3.3][pickaxe] +: Класична праця про Ruby англійською мовою. Нещодавно оновлена до Ruby 3.3. + +[The Well-Grounded Rubyist][grounded] +: Туторіал, що починається з вашої першої програми на Ruby й веде аж до + складних тем, як-от reflection, threading і рекурсія. + +#### Середній рівень + +[Practical OOD in Ruby (POODR)][poodr] +: Історія програміста про те, як писати об’єктно-орієнтований код. + +#### Просунутий рівень + +[Metaprogramming][meta] +: Пояснює метапрограмування в простому, приземленому стилі. + +[Ruby Under a Microscope (RUM)][microscope] +: Ілюстрований путівник внутрішнім устроєм Ruby. + +### Документація спільноти + +Ці сайти з документацією підтримує спільнота Ruby. + +[RubyDoc.info][16] +: Єдиний вебсайт для довідкової документації про gem-и Ruby та Ruby-проєкти + на GitHub. + +[RubyAPI.org][rubyapi-org] +: Зручно знаходити та переглядати класи, модулі й методи Ruby. + +[ruby-doc.org][39] +: Онлайн документація API + +[DevDocs.io][40] +: Онлайн документація API + +[Ruby QuickRef][42] +: Швидка довідка Ruby + +[rubyreferences][43] +: Повний довідник мови + детальний changelog змін мови. + +### Керівництва зі стилю + +[rubystyle.guide][44] +: Керівництво зі стилю Ruby від RuboCop + +[RuboCop][45] +: Автоматизоване застосування їхнього керівництва зі стилю. + +[Shopify][46] +: Керівництво зі стилю Ruby від Shopify + +[GitLab][47] +: Керівництво зі стилю Ruby від Gitlab + +[Airbnb][48] +: Керівництво зі стилю Ruby від Airbnb + +[w3resource][49] +: Керівництво зі стилю Ruby від W3 + +# Інструменти + +[IRB][50] +: Інтерактивний Ruby Read-Eval-Print-Loop (REPL) + +[Pry][51] +: Альтернативний Ruby REPL + +[Rake][52] +: Утиліта збірки для Ruby на кшталт make. + +[RI][53] +: (Ruby Information) — утиліта командного рядка Ruby, що надає швидкий + і зручний доступ до документації Ruby. + +[RBS][54] +: Типові сигнатури для Ruby + +[TypeProf][55] +: Експериментальний інтерпретатор Ruby на рівні типів для тестування + та розуміння коду Ruby. + +[Steep][56] +: Статичний перевіряч типів для Ruby. + +### Редактори та IDE + +Для написання коду на Ruby можна використовувати стандартний редактор +вашої операційної системи. Проте для ефективнішого кодування варто +обирати редактор із базовою підтримкою Ruby (наприклад, підсвічуванням +синтаксису, переглядом файлів) або інтегроване середовище розробки +з розширеними можливостями (наприклад, автодоповнення, рефакторинг, +підтримка тестів). + +Ось список популярних редакторів, якими користуються Rubyists, поділений +за кривою навчання: + +* Дні + * [Sublime Text][37] (платний) + * [Visual Studio Code][vscode] + * [Zed][zed] +* Місяці + * [RubyMine][27] (платний) +* "Роки" (тобто ви роками будете вивчати нові речі про нього) + * [Emacs][20] із [Ruby mode][21] або [Enhanced Ruby mode][enh-ruby-mode] + * [Vim][25] із плагіном [vim-ruby][26] + * [NeoVim][neovim] + +Усі ці редактори підтримують Language Server Protocol (LSP), +або за замовчуванням, або через плагіни LSP. Shopify [ruby-lsp][ruby-lsp] +— один із найпопулярніших language server для Ruby і +[підтримує всі перелічені редактори][ruby-lsp-supported-editors]. + +### Старі матеріали / ресурси + +Ці посилання раніше були більш помітними, але давно не оновлювалися. + +[Ruby Koans][2] +: Koans ведуть вас шляхом просвітлення, щоб вивчити Ruby. Мета — + опанувати мову Ruby, її синтаксис, структуру та деякі типові функції + й бібліотеки. Ми також навчаємо культурі. + +[Ruby Essentials][7] +: Безкоштовна онлайн-книга, створена як стислий і простий посібник + для вивчення Ruby. + +[Why’s (Poignant) Guide to Ruby][5] +: Нетрадиційна, але цікава книга, що навчає Ruby через історії, гумор + та комікси. Спочатку створена *why the lucky stiff*, ця книга + залишається класикою для тих, хто вивчає Ruby. + +[Learn Ruby the Hard Way][38] +: Дуже хороший набір вправ із поясненнями, які ведуть вас від основ Ruby + до ООП і веброзробки. + +[Programming Ruby][9] +: Класична праця про Ruby англійською мовою, перше видання + [книги Pragmatic Programmers][10] доступне безкоштовно онлайн. + +[The Ruby Programming Wikibook][12] +: Безкоштовний онлайн-посібник з матеріалами для початкового та середнього + рівня плюс ґрунтовний довідник мови. + +[1]: https://try.ruby-lang.org/ +[2]: https://rubykoans.com/ +[5]: https://poignant.guide +[7]: https://www.techotopia.com/index.php/Ruby_Essentials +[8]: https://pine.fm/LearnToProgram/ +[9]: https://ruby-doc.com/docs/ProgrammingRuby/ +[10]: https://pragprog.com/titles/ruby5/programming-ruby-3-3-5th-edition/ +[12]: https://en.wikibooks.org/wiki/Ruby_programming_language +[16]: https://www.rubydoc.info/ +[20]: https://www.gnu.org/software/emacs/ +[21]: https://www.emacswiki.org/emacs/RubyMode +[25]: https://www.vim.org/ +[26]: https://github.com/vim-ruby/vim-ruby +[27]: https://www.jetbrains.com/ruby/ +[37]: https://www.sublimetext.com/ +[38]: https://learncodethehardway.org/ruby/ +[39]: https://ruby-doc.org/ +[40]: https://devdocs.io/ruby/ +[42]: https://www.zenspider.com/ruby/quickref.html +[43]: https://rubyreferences.github.io/ +[44]: https://rubystyle.guide/ +[45]: https://github.com/rubocop/ruby-style-guide +[46]: https://ruby-style-guide.shopify.dev/ +[47]: https://docs.gitlab.com/ee/development/backend/ruby_style_guide.html +[48]: https://github.com/airbnb/ruby +[49]: https://www.w3resource.com/ruby/ruby-style-guide.php +[50]: https://github.com/ruby/irb +[51]: https://github.com/pry/pry +[52]: https://github.com/ruby/rake +[53]: https://ruby.github.io/rdoc/RI_md.html +[54]: https://github.com/ruby/rbs +[55]: https://github.com/ruby/typeprof +[56]: https://github.com/soutaro/steep +[codecademy]: https://www.codecademy.com/learn/learn-ruby +[docs-rlo]: https://docs.ruby-lang.org/en +[docs-rlo-3.4]: https://docs.ruby-lang.org/en/3.4 +[docs-rlo-master]: https://docs.ruby-lang.org/en/master +[docs-rlo-extension]: https://docs.ruby-lang.org/en/master/extension_rdoc.html +[enh-ruby-mode]: https://github.com/zenspider/enhanced-ruby-mode/ +[exercism]: https://exercism.org/tracks/ruby +[grounded]: https://www.manning.com/books/the-well-grounded-rubyist-third-edition +[meta]: https://pragprog.com/titles/ppmetr2/metaprogramming-ruby-2/ +[microscope]: https://patshaughnessy.net/ruby-under-a-microscope +[neovim]: https://neovim.io/ +[odin]: https://www.theodinproject.com/paths/full-stack-ruby-on-rails/courses/ruby +[pickaxe]: https://pragprog.com/titles/ruby5/programming-ruby-3-3-5th-edition/ +[poodr]: https://www.poodr.com/ +[ruby-lsp]: https://github.com/Shopify/ruby-lsp +[ruby-lsp-supported-editors]: https://github.com/Shopify/ruby-lsp#editor-plugins +[rubyapi-org]: https://rubyapi.org/ +[rubyin20]: /ua/documentation/quickstart/ +[vscode]: https://code.visualstudio.com/ +[zed]: https://zed.dev/ diff --git a/ua/documentation/installation/index.md b/ua/documentation/installation/index.md new file mode 100644 index 0000000000..1b05486eae --- /dev/null +++ b/ua/documentation/installation/index.md @@ -0,0 +1,438 @@ +--- +layout: page +title: "Встановлення Ruby" +lang: ua +--- + +За допомогою пакетних менеджерів або сторонніх інструментів у вас є +багато варіантів для встановлення й керування Ruby. +{: .summary} + +Можливо, Ruby уже встановлений на вашому комп’ютері. Перевірте це у +[термінальному емуляторі][terminal], ввівши: + +{% highlight sh %} +ruby -v +{% endhighlight %} + +Має відобразитися інформація про встановлену версію Ruby. + +## Оберіть метод встановлення + +Є кілька способів встановити Ruby: + +* У UNIX-подібній ОС найпростіше використовувати **пакетний менеджер** + системи. Однак пакетна версія Ruby може бути не найновішою. +* **Інсталятори** можна використовувати для встановлення конкретної або + кількох версій Ruby. Також є інсталятор для Windows. +* **Менеджери** допомагають перемикатися між кількома версіями Ruby + у вашій системі. +* Зрештою, ви можете **зібрати Ruby з вихідного коду**. + +У Windows 10 ви також можете використовувати +[Windows Subsystem for Linux][wsl], щоб установити одну з підтримуваних +дистрибутивів Linux і застосувати будь-який із доступних методів +встановлення в цій системі. + +Ось доступні методи встановлення: + +* [Пакетні менеджери](#package-management-systems) + * [Debian, Ubuntu](#apt) + * [CentOS, Fedora, RHEL](#yum) + * [Snap](#snap) + * [Gentoo](#portage) + * [Arch Linux](#pacman) + * [macOS](#homebrew) + * [FreeBSD](#freebsd) + * [OpenBSD](#openbsd) + * [OpenIndiana](#openindiana) + * [Windows Package Manager](#winget) + * [Chocolatey package manager для Windows](#chocolatey) + * [Інші дистрибутиви](#other-systems) +* [Інсталятори](#installers) + * [ruby-build](#ruby-build) + * [ruby-install](#ruby-install) + * [RubyInstaller](#rubyinstaller) (Windows) + * [Ruby Stack](#rubystack) +* [Менеджери](#managers) + * [asdf-vm](#asdf-vm) + * [chruby](#chruby) + * [mise-en-place](#mise-en-place) + * [rbenv](#rbenv) + * [rbenv для Windows](#rbenv-for-windows) + * [RVM](#rvm) + * [uru](#uru) +* [Збирання з вихідного коду](#building-from-source) + + +## Пакетні менеджери +{: #package-management-systems} + +Якщо ви не можете компілювати Ruby самостійно і не хочете використовувати +сторонні інструменти, скористайтеся пакетним менеджером вашої системи +для встановлення Ruby. + +Деякі члени спільноти Ruby вважають, що пакетних менеджерів для встановлення +Ruby слід уникати й натомість використовувати спеціалізовані інструменти. + +Можливо, основні пакетні менеджери встановлять старіші версії Ruby замість +найновішого релізу. Щоб використовувати найновіший реліз, перевірте, що +назва пакета відповідає номеру версії. Або використовуйте спеціалізований +[інсталятор][installers]. + + +### apt (Debian або Ubuntu) +{: #apt} + +Debian GNU/Linux і Ubuntu використовують пакетний менеджер apt. Ви можете +скористатися ним так: + +{% highlight sh %} +$ sudo apt-get install ruby-full +{% endhighlight %} + + +### yum (CentOS, Fedora або RHEL) +{: #yum} + +CentOS, Fedora і RHEL використовують пакетний менеджер yum. +Ви можете скористатися ним так: + +{% highlight sh %} +$ sudo yum install ruby +{% endhighlight %} + +Встановлена версія зазвичай є найновішою версією Ruby, доступною на момент +випуску відповідної версії дистрибутива. + + +### snap (Ubuntu або інші дистрибутиви Linux) +{: #snap} + +Snap — пакетний менеджер, розроблений компанією Canonical. +Він доступний «з коробки» в Ubuntu, але також працює у багатьох +інших дистрибутивах Linux. +Використовуйте так: + +{% highlight sh %} +$ sudo snap install ruby --classic +{% endhighlight %} + +Ми маємо кілька каналів для кожної молодшої серії Ruby. +Наприклад, ці команди перемикаються на Ruby 2.3: + +{% highlight sh %} +$ sudo snap switch ruby --channel=2.3/stable +$ sudo snap refresh +{% endhighlight %} + + +### portage (Gentoo) +{: #portage} + +Gentoo використовує пакетний менеджер portage. + +{% highlight sh %} +$ sudo emerge dev-lang/ruby +{% endhighlight %} + +Щоб встановити конкретну версію, встановіть `RUBY_TARGETS` у вашому `make.conf`. +Дивіться [сайт Gentoo Ruby Project][gentoo-ruby] для деталей. + + +### pacman (Arch Linux) +{: #pacman} + +Arch Linux використовує пакетний менеджер pacman. +Щоб отримати Ruby, виконайте: + +{% highlight sh %} +$ sudo pacman -S ruby +{% endhighlight %} + +Це має встановити останню стабільну версію Ruby. + + +### Homebrew (macOS) +{: #homebrew} + +Версії Ruby 2.0 і вище включені за замовчуванням у релізи macOS +принаймні з El Capitan (10.11). + +[Homebrew][homebrew] — поширений пакетний менеджер у macOS. +Встановити Ruby через Homebrew легко: + +{% highlight sh %} +$ brew install ruby +{% endhighlight %} + +Це має встановити останню версію Ruby. + + +### FreeBSD +{: #freebsd} + +FreeBSD пропонує як попередньо зібрані, так і вихідні способи встановлення Ruby. +Попередньо зібрані пакунки можна встановити через інструмент pkg: + +{% highlight sh %} +$ pkg install ruby +{% endhighlight %} + +Вихідний спосіб встановлення доступний через +[колекцію Ports][freebsd-ports-collection]. Це корисно, якщо ви хочете +налаштувати параметри збірки. + +Детальніше про Ruby та екосистему на FreeBSD — на сайті +[FreeBSD Ruby Project][freebsd-ruby]. + + +### OpenBSD +{: #openbsd} + +OpenBSD, а також його дистрибутив adJ мають пакети для трьох основних +версій Ruby. Наступна команда дозволяє переглянути доступні версії та +встановити одну з них: + +{% highlight sh %} +$ doas pkg_add ruby +{% endhighlight %} + +Ви можете встановлювати кілька основних версій поруч, оскільки їхні +бінарні файли мають різні назви (наприклад, `ruby27`, `ruby26`). + +Гілка `HEAD` колекції портів OpenBSD може містити найсвіжішу версію Ruby +для цієї платформи через кілька днів після релізу; дивіться +[каталог lang/ruby у найсвіжішій колекції портів][openbsd-current-ruby-ports]. + + +### Ruby на OpenIndiana +{: #openindiana} + +Щоб встановити Ruby на [OpenIndiana][openindiana], використовуйте клієнт +Image Packaging System (IPS). +Він встановить бінарні файли Ruby і RubyGems безпосередньо з репозиторіїв +OpenIndiana. Це просто: + +{% highlight sh %} +$ pkg install runtime/ruby +{% endhighlight %} + +Проте сторонні інструменти можуть бути хорошим способом отримати +найновішу версію Ruby. + +### Windows Package Manager +{: #winget} + +У Windows можна використовувати +[Windows Package Manager CLI](https://github.com/microsoft/winget-cli) +для встановлення Ruby: + +{% highlight ps1 %} +> winget install RubyInstallerTeam.Ruby.{MAJOR}.{MINOR} +# Example +> winget install RubyInstallerTeam.Ruby.3.2 +# To see all versions available +> winget search RubyInstallerTeam.Ruby +# Note: if you are installing ruby for projects, you may want to install RubyWithDevKit +> winget install RubyInstallerTeam.RubyWithDevKit.3.2 +{% endhighlight %} + +### Chocolatey package manager для Windows +{: #chocolatey} + +У Windows також можна використовувати +[Chocolatey Package Manager](https://chocolatey.org/install) +для встановлення Ruby: + +{% highlight sh %} +> choco install ruby +{% endhighlight %} + +Він повторно використає наявний `msys2` або встановить власний для +повного середовища розробки Ruby. + +### Інші дистрибутиви +{: #other-systems} + +В інших системах ви можете знайти Ruby у репозиторії пакетів вашого +дистрибутива Linux. Альтернативно ви можете використати +[сторонній інсталятор][installers]. + + +## Інсталятори +{: #installers} + +Якщо версія Ruby, яку надає ваша система або пакетний менеджер, застаріла, +новішу можна встановити за допомогою стороннього інсталятора. + +Деякі інсталятори дозволяють встановлювати кілька версій на одній системі; +пов’язані менеджери допомагають перемикатися між різними Ruby. + +Якщо ви плануєте використовувати [RVM](#rvm) як менеджер версій, окремий +інсталятор не потрібен — він має власний. + + +### ruby-build +{: #ruby-build} + +[ruby-build][ruby-build] — плагін для [rbenv](#rbenv), який дозволяє +компілювати та встановлювати різні версії Ruby. ruby-build також може +використовуватися як окрема програма без rbenv. Він доступний для macOS, +Linux та інших UNIX-подібних ОС. + + +### ruby-install +{: #ruby-install} + +[ruby-install][ruby-install] дозволяє компілювати та встановлювати різні +версії Ruby у довільні каталоги. [chruby](#chruby) — допоміжний інструмент +для перемикання між версіями Ruby. Доступний для macOS, Linux та інших +UNIX-подібних ОС. + + +### RubyInstaller +{: #rubyinstaller} + +У Windows [RubyInstaller][rubyinstaller] надає все необхідне для +налаштування повного середовища розробки Ruby. + +Просто завантажте його, запустіть і готово! + + +### Ruby Stack +{: #rubystack} + +Якщо ви встановлюєте Ruby для використання Ruby on Rails, +можете скористатися таким інсталятором: + +* [Bitnami Ruby Stack][rubystack] надає повне середовище розробки для Rails. + Підтримує macOS, Linux, Windows, віртуальні машини та образи для хмари. + + +## Менеджери +{: #managers} + +Багато Rubyists використовують менеджери Ruby для керування кількома +версіями Ruby. Вони дозволяють легко або навіть автоматично перемикатися +між версіями Ruby залежно від проєкту, а також мають інші переваги, але +офіційно не підтримуються. Втім, підтримку можна знайти у відповідних +спільнотах. + + +### asdf-vm +{: #asdf-vm} + +[asdf-vm][asdf-vm] — розширюваний менеджер версій, який може керувати +версіями runtime кількох мов на рівні проєкту. Вам знадобиться плагін +[asdf-ruby][asdf-ruby] (який, своєю чергою, використовує [ruby-build](#ruby-build)) +для встановлення Ruby. + + +### chruby +{: #chruby} + +[chruby][chruby] дозволяє перемикатися між кількома Ruby. Він може +керувати Ruby, встановленими через [ruby-install](#ruby-install), або +збірками з вихідного коду. + + +### mise-en-place +{: #mise-en-place} + +[mise-en-place][mise-en-place] дозволяє перемикатися між кількома Ruby без +потреби в додаткових інструментах. Він автоматично керує встановленнями й +містить [gem backend](https://mise.jdx.dev/dev-tools/backends/gem.html) +для керування версіями CLI, написаних на Ruby. Підтримує UNIX-подібні та +Windows ОС. + + +### rbenv +{: #rbenv} + +[rbenv][rbenv] дозволяє керувати кількома встановленнями Ruby. За +замовчуванням він не встановлює Ruby, але його плагін [ruby-build](#ruby-build) +може. Обидва інструменти доступні для macOS, Linux та інших UNIX-подібних ОС. + + +### rbenv для Windows +{: #rbenv-for-windows} + +[rbenv for Windows][rbenv-for-windows] дозволяє встановлювати й керувати +кількома встановленнями Ruby у Windows. Він написаний на PowerShell, що +надає нативний спосіб використання Ruby для користувачів Windows. +Крім того, інтерфейс командного рядка сумісний з [rbenv][rbenv] +на UNIX-подібних системах. + + +### RVM ("Ruby Version Manager") +{: #rvm} + +[RVM][rvm] дозволяє встановлювати й керувати кількома встановленнями +Ruby у вашій системі. Він також може керувати різними gemset-ами. +Доступний для macOS, Linux та інших UNIX-подібних ОС. + + +### RVM 4 Windows +{: #rvm-windows} + +[RVM 4 Windows][rvm-windows] дозволяє встановлювати й керувати кількома +встановленнями Ruby у Windows. Це клон оригінального RVM і підтримує +класичний командний рядок, а також PowerShell, надаючи той самий +інтерфейс командного рядка, що й оригінальний RVM. + + +### uru +{: #uru} + +[Uru][uru] — легкий кросплатформний інструмент командного рядка, що +допомагає використовувати кілька Ruby на macOS, Linux або Windows. + + +## Збирання з вихідного коду +{: #building-from-source} + +Звісно, Ruby можна встановити з вихідного коду. +[Завантажте][download] та розпакуйте tarball, після чого виконайте: + +{% highlight sh %} +$ ./configure +$ make +$ sudo make install +{% endhighlight %} + +За замовчуванням Ruby буде встановлено у `/usr/local`. +Щоб змінити це, передайте опцію `--prefix=DIR` до скрипта `./configure`. + +Більше інформації про збирання з вихідного коду можна знайти в +[інструкціях збирання Ruby][building-ruby]. + +Втім, використання сторонніх інструментів або пакетних менеджерів може бути +кращою ідеєю, адже встановлений Ruby не буде керуватися жодними інструментами. + + +[rvm]: http://rvm.io/ +[rvm-windows]: https://github.com/magynhard/rvm-windows#readme +[rbenv]: https://github.com/rbenv/rbenv#readme +[rbenv-for-windows]: https://github.com/RubyMetric/rbenv-for-windows#readme +[ruby-build]: https://github.com/rbenv/ruby-build#readme +[ruby-install]: https://github.com/postmodern/ruby-install#readme +[chruby]: https://github.com/postmodern/chruby#readme +[uru]: https://bitbucket.org/jonforums/uru +[rubyinstaller]: https://rubyinstaller.org/ +[rubystack]: http://bitnami.com/stack/ruby/installer +[openindiana]: http://openindiana.org/ +[gentoo-ruby]: http://www.gentoo.org/proj/en/prog_lang/ruby/ +[freebsd-ruby]: https://wiki.freebsd.org/Ruby +[freebsd-ports-collection]: https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/ports-using.html +[homebrew]: http://brew.sh/ +[terminal]: https://en.wikipedia.org/wiki/List_of_terminal_emulators +[download]: /ua/downloads/ +[installers]: /ua/documentation/installation/#installers +[building-ruby]: https://github.com/ruby/ruby/blob/master/doc/contributing/building_ruby.md +[wsl]: https://docs.microsoft.com/en-us/windows/wsl/about +[asdf-vm]: https://asdf-vm.com/ +[asdf-ruby]: https://github.com/asdf-vm/asdf-ruby +[mise-en-place]: https://mise.jdx.dev +[mise-en-place-ruby]: https://mise.jdx.dev/lang/ruby.html +[openbsd-current-ruby-ports]: https://cvsweb.openbsd.org/cgi-bin/cvsweb/ports/lang/ruby/?only_with_tag=HEAD diff --git a/ua/documentation/quickstart/2/index.md b/ua/documentation/quickstart/2/index.md new file mode 100644 index 0000000000..ee6ffa56d2 --- /dev/null +++ b/ua/documentation/quickstart/2/index.md @@ -0,0 +1,121 @@ +--- +layout: page +title: "Ruby за двадцять хвилин" +lang: ua + +header: | + +Ruby за двадцять хвилин
+ +--- + +Як сказати “Hello” багато разів, не втомлюючи пальці? Потрібно визначити метод! + +{% highlight irb %} +irb(main):010:0> def hi +irb(main):011:1> puts "Hello World!" +irb(main):012:1> end +=> :hi +{% endhighlight %} + +Код `def hi` починає визначення методу. Він повідомляє Ruby, що ми +визначаємо метод і що його назва — `hi`. Наступний рядок — це тіло методу, +той самий рядок, який ми бачили раніше: `puts "Hello World"`. +Нарешті, останній рядок `end` повідомляє Ruby, що ми завершили визначення +методу. Відповідь Ruby `=> :hi` говорить, що він зрозумів завершення. +Ця відповідь могла б бути `=> nil` для Ruby 2.0 і попередніх версій. +Але це тут неважливо, тож продовжимо. + +## Коротке, повторюване життя методу + +Тепер спробуймо викликати цей метод кілька разів: + +{% highlight irb %} +irb(main):013:0> hi +Hello World! +=> nil +irb(main):014:0> hi() +Hello World! +=> nil +{% endhighlight %} + +Що ж, це було просто. Викликати метод у Ruby так само легко, як просто +згадати його ім’я. Якщо метод не приймає параметрів — це все, що потрібно. +Можна додати порожні дужки, якщо хочете, але вони не обов’язкові. + +А що, якщо ми хочемо привітатися з однією людиною, а не з усім світом? +Просто перевизначте `hi`, щоб він приймав ім’я як параметр. + +{% highlight irb %} +irb(main):015:0> def hi(name) +irb(main):016:1> puts "Hello #{name}!" +irb(main):017:1> end +=> :hi +irb(main):018:0> hi("Matz") +Hello Matz! +=> nil +{% endhighlight %} + +Отже, працює… але давайте на хвилину розберемося, що тут відбувається. + +## Підстановки у рядку + +Що означає `#{name}`? Це спосіб Ruby вставити щось у рядок. +Те, що між фігурними дужками, перетворюється на рядок (якщо ще не є ним), +а потім підставляється у зовнішній рядок у цьому місці. Ви також можете +використати це, щоб правильно капіталізувати ім’я: + +{% highlight irb %} +irb(main):019:0> def hi(name = "World") +irb(main):020:1> puts "Hello #{name.capitalize}!" +irb(main):021:1> end +=> :hi +irb(main):022:0> hi "chris" +Hello Chris! +=> nil +irb(main):023:0> hi +Hello World! +=> nil +{% endhighlight %} + +Тут ще дві хитрощі. Перша — ми знову викликаємо метод без дужок. +Якщо очевидно, що ви робите, дужки необов’язкові. Друга — параметр +за замовчуванням `World`. Це означає: “Якщо ім’я не передано, використовуй +значення за замовчуванням `"World"`”. + +## Перетворення на привітальника + +А що, якщо ми хочемо справжнього привітальника, який пам’ятатиме ваше +ім’я, вітатиме вас і завжди ставитиметься з повагою? Для цього можна +використати об’єкт. Створімо клас “Greeter”. + +{% highlight irb %} +irb(main):024:0> class Greeter +irb(main):025:1> def initialize(name = "World") +irb(main):026:2> @name = name +irb(main):027:2> end +irb(main):028:1> def say_hi +irb(main):029:2> puts "Hi #{@name}!" +irb(main):030:2> end +irb(main):031:1> def say_bye +irb(main):032:2> puts "Bye #{@name}, come back soon." +irb(main):033:2> end +irb(main):034:1> end +=> :say_bye +{% endhighlight %} + +Нове ключове слово тут — `class`. Воно визначає новий клас Greeter і +набір методів для цього класу. Зверніть увагу на `@name`. Це змінна +екземпляра, доступна для всіх методів класу. Як бачите, її використовують +`say_hi` і `say_bye`. + +Тож як запустити цей клас Greeter? +[Створімо об’єкт.](../3/) diff --git a/ua/documentation/quickstart/3/index.md b/ua/documentation/quickstart/3/index.md new file mode 100644 index 0000000000..cbd4a96f2d --- /dev/null +++ b/ua/documentation/quickstart/3/index.md @@ -0,0 +1,225 @@ +--- +layout: page +title: "Ruby за двадцять хвилин" +lang: ua + +header: | + +Ruby за двадцять хвилин
+ +--- + +Тепер створімо об’єкт привітальника та використаємо його: + +{% highlight irb %} +irb(main):035:0> greeter = Greeter.new("Pat") +=> #Ruby за двадцять хвилин
+ +--- + +Розгляньмо наш новий застосунок глибше. Зверніть увагу на перші рядки, +які починаються з решітки (#). У Ruby все, що знаходиться в рядку після +решітки, є коментарем і ігнорується інтерпретатором. Перший рядок файлу — +особливий випадок і під Unix-подібними ОС повідомляє shell, як запускати +файл. Решта коментарів потрібна лише для ясності. + +Наш метод `say_hi` став трохи складнішим: + +{% highlight ruby %} +# Say hi to everybody +def say_hi + if @names.nil? + puts "..." + elsif @names.respond_to?("each") + # @names is a list of some kind, iterate! + @names.each do |name| + puts "Hello #{name}!" + end + else + puts "Hello #{@names}!" + end +end +{% endhighlight %} + +Тепер він дивиться на змінну екземпляра `@names`, щоб приймати рішення. +Якщо вона дорівнює nil, він просто виводить три крапки. Немає сенсу +вітатися з ніким, правда? + +## Перебір і цикли — тобто ітерація + +Якщо об’єкт `@names` відповідає на `each`, це означає, що його можна +ітератувати. Отже, ми ітеруємо його і вітаємо кожну людину по черзі. +Зрештою, якщо `@names` — це щось інше, Ruby автоматично перетворює його +на рядок і виконує стандартне привітання. + +Розгляньмо цей ітератор детальніше: + +{% highlight ruby %} +@names.each do |name| + puts "Hello #{name}!" +end +{% endhighlight %} + +`each` — це метод, який приймає блок коду і виконує його для кожного +елемента списку; а частина між `do` та `end` — це саме такий блок. +Блок схожий на анонімну функцію або `lambda`. Змінна між вертикальними +рисками — це параметр блоку. + +У цьому випадку для кожного елемента списку `name` прив’язується до цього +елемента, після чого виконується вираз `puts "Hello #{name}!"`. + +Більшість інших мов програмування проходить список за допомогою циклу `for`, +який у C виглядає приблизно так: + +{% highlight c %} +for (i=0; iRuby за двадцять хвилин
+ +--- + +## Вступ + +Це невеликий туторіал з Ruby, який має зайняти не більше 20 хвилин. +Передбачається, що Ruby уже встановлено. +(Якщо Ruby немає на вашому комп’ютері, [встановіть][installation] його +перед початком.) + +## Інтерактивний Ruby + +Ruby постачається з програмою, яка показує результати будь-яких Ruby- +виразів, що ви їй передаєте. Гра з Ruby у таких інтерактивних сесіях — +чудовий спосіб вивчити мову. + +Відкрийте IRB (Interactive Ruby). + +* Якщо ви використовуєте **macOS**, відкрийте `Terminal` і введіть `irb`, + потім натисніть Enter. +* Якщо ви використовуєте **Linux**, відкрийте shell і введіть `irb`, + потім натисніть Enter. +* Якщо ви використовуєте **Windows**, відкрийте `Interactive Ruby` у + розділі Ruby вашого меню "Пуск". + +{% highlight irb %} +irb(main):001:0> +{% endhighlight %} + +Гаразд, він відкритий. Що далі? + +Введіть це: `"Hello World"` + +{% highlight irb %} +irb(main):001:0> "Hello World" +=> "Hello World" +{% endhighlight %} + +## Ruby вас послухався! + +Що щойно сталося? Невже ми написали найкоротшу у світі програму +“Hello World”? Не зовсім. Другий рядок — це лише спосіб IRB +повідомити результат останнього виразу, який він обчислив. Якщо ми +хочемо вивести “Hello World”, потрібно трохи більше: + +{% highlight irb %} +irb(main):002:0> puts "Hello World" +Hello World +=> nil +{% endhighlight %} + +`puts` — базова команда для виведення в Ruby. Але що означає `=> nil`? +Це результат виразу. `puts` завжди повертає nil — значення Ruby, що +означає абсолютно нічого. + +## Ваш безкоштовний калькулятор тут + +Ми вже можемо використовувати IRB як простий калькулятор: + +{% highlight irb %} +irb(main):003:0> 3+2 +=> 5 +{% endhighlight %} + +Три плюс два. Достатньо просто. А як щодо трьох, помножених на два? +Ви можете ввести це вручну — рядок короткий. Але ви також можете +піднятися вгору та змінити введений рядок. Натисніть **стрілку вгору** +на клавіатурі й подивіться, чи з’явиться рядок з `3+2`. Якщо так, +використайте стрілку вліво, щоб перейти відразу після `+`, а потім +натисніть Backspace, щоб замінити `+` на `*`. + +{% highlight irb %} +irb(main):004:0> 3*2 +=> 6 +{% endhighlight %} + +Далі спробуймо три в квадраті: + +{% highlight irb %} +irb(main):005:0> 3**2 +=> 9 +{% endhighlight %} + +У Ruby `**` означає "в степені". Але що, якщо ви хочете піти іншим +шляхом і знайти квадратний корінь із числа? + +{% highlight irb %} +irb(main):006:0> Math.sqrt(9) +=> 3.0 +{% endhighlight %} + +Гаразд, що це було? Якщо ви здогадалися, “обчислення квадратного кореня +із дев’яти”, ви праві. Але розгляньмо детальніше. По-перше, що таке +`Math`? + +## Модулі групують код за темами + +`Math` — вбудований модуль для математики. Модулі виконують дві ролі в +Ruby. Тут показана одна з них: групування схожих методів під знайомою +назвою. `Math` також містить методи на кшталт `sin()` і `tan()`. + +Далі стоїть крапка. Що вона робить? Крапка — це спосіб вказати отримувача +повідомлення. А саме повідомлення — це `sqrt(9)`, що означає виклик методу +`sqrt` (скорочення від “square root”) з параметром `9`. + +Результат цього виклику — значення `3.0`. Ви могли помітити, що це не +просто `3`. Це тому, що квадратний корінь числа не завжди є цілим, +тому метод завжди повертає число з плаваючою комою. + +А що, якщо ми хочемо зберегти результат цих обчислень? Присвойте +результат змінній. + +{% highlight irb %} +irb(main):007:0> a = 3 ** 2 +=> 9 +irb(main):008:0> b = 4 ** 2 +=> 16 +irb(main):009:0> Math.sqrt(a+b) +=> 5.0 +{% endhighlight %} + +Як би не було зручно мати калькулятор, ми відходимо від традиційного +“Hello World”, на якому мають зосереджуватися вступні туторіали… +[тож повернімося до нього.](2/) + +[installation]: /ua/documentation/installation/ diff --git a/ua/documentation/ruby-from-other-languages/index.md b/ua/documentation/ruby-from-other-languages/index.md new file mode 100644 index 0000000000..b6cce00e4a --- /dev/null +++ b/ua/documentation/ruby-from-other-languages/index.md @@ -0,0 +1,420 @@ +--- +layout: page +title: "Ruby з інших мов" +lang: ua +--- + +Коли ви вперше дивитеся на код Ruby, він, ймовірно, нагадає вам інші +мови програмування, з якими ви працювали. Це зроблено навмисно. Значна +частина синтаксису знайома користувачам Perl, Python і Java (та інших +мов), тож якщо ви їх використовували, вивчити Ruby буде нескладно. +{: .summary} + +Цей документ складається з двох основних розділів. Перший — це стислий +огляд того, чого очікувати, переходячи з мови *X* на Ruby. Другий розділ +розглядає ключові особливості мови та те, як вони співвідносяться з тим, +що вам уже знайомо. + +## Чого очікувати: *мова X* → Ruby + +* [Перехід на Ruby з C та C++](to-ruby-from-c-and-cpp/) +* [Перехід на Ruby з Java](to-ruby-from-java/) +* [Перехід на Ruby з Perl](to-ruby-from-perl/) +* [Перехід на Ruby з PHP](to-ruby-from-php/) +* [Перехід на Ruby з Python](to-ruby-from-python/) + +## Важливі особливості мови та деякі підводні камені + +Нижче наведено поради й підказки щодо ключових особливостей Ruby, які +ви побачите під час вивчення. + +### Ітерація + +Дві особливості Ruby, які трохи відрізняються від того, що ви могли +бачити раніше, і до яких потрібно звикнути, — це “блоки” та ітератори. +Замість проходу по індексу (як у C, C++ або Java до 1.5) або проходу по +списку (як Perl `for (@a) {...}` чи Python `for i in aList: ...`), у Ruby +ви дуже часто побачите таке: + +{% highlight ruby %} +some_list.each do |this_item| + # We're inside the block. + # deal with this_item. +end +{% endhighlight %} + +Детальніше про `each` (і його друзів `collect`, `find`, `inject`, +`sort` тощо) дивіться `ri Enumerable` (а потім `ri Enumerable#some_method`). + +### Усе має значення + +Немає різниці між виразом і оператором. Усе має значення, навіть якщо +це значення — `nil`. Можливо таке: + +{% highlight ruby %} +x = 10 +y = 11 +z = if x < y + true + else + false + end +z # => true +{% endhighlight %} + +### Символи — це не полегшені рядки + +Багато новачків у Ruby мають труднощі з розумінням того, що таке символи +і для чого вони потрібні. + +Символи найкраще описати як ідентичності. Символ — це про **хто** він, +а не **що** він. Запустіть `irb` і подивіться різницю: + +{% highlight irb %} +irb(main):001:0> :george.object_id == :george.object_id +=> true +irb(main):002:0> "george".object_id == "george".object_id +=> false +irb(main):003:0> +{% endhighlight %} + +Метод `object_id` повертає ідентичність об’єкта. Якщо два об’єкти мають +однаковий `object_id`, це один і той самий об’єкт (посилаються на той самий +об’єкт у пам’яті). + +Як видно, після того як ви один раз використали символ, будь-який символ +з такими самими символами посилається на той самий об’єкт у пам’яті. Для +будь-яких двох символів, що представляють однакові символи, `object_id` +співпадають. + +Тепер подивіться на рядок (“george”). `object_id` не співпадають. Це +означає, що вони посилаються на два різні об’єкти в пам’яті. Кожного разу, +коли ви створюєте новий рядок, Ruby виділяє для нього пам’ять. + +Якщо ви сумніваєтеся, використовувати символ чи рядок, подумайте, що +важливіше: ідентичність об’єкта (наприклад, ключ у Hash), чи вміст +(у прикладі вище — “george”). + +### Усе є об’єктом + +“Усе є об’єктом” — не просто гіпербола. Навіть класи та цілі числа — +об’єкти, і з ними можна робити те саме, що й з будь-яким іншим об’єктом: + +{% highlight ruby %} +# This is the same as +# class MyClass +# attr_accessor :instance_var +# end +MyClass = Class.new do + attr_accessor :instance_var +end +{% endhighlight %} + +### Константи — не зовсім константи + +Константи насправді не є константами. Якщо ви зміните вже ініціалізовану +константу, Ruby видасть попередження, але не зупинить програму. Це не +означає, що **слід** перевизначати константи. + +### Конвенції іменування + +Ruby дотримується певних конвенцій іменування. Якщо ідентифікатор +починається з великої літери — це константа. Якщо з символу долара (`$`) +— глобальна змінна. Якщо з `@` — змінна екземпляра. Якщо з `@@` — змінна класу. + +Назви методів, однак, можуть починатися з великої літери. Це може +спричиняти плутанину, як показано нижче: + +{% highlight ruby %} +Constant = 10 +def Constant + 11 +end +{% endhighlight %} + +Тепер `Constant` дорівнює 10, але `Constant()` дорівнює 11. + +### Іменовані аргументи + +Як і в Python, починаючи з Ruby 2.0, методи можна визначати з +іменованими аргументами: + +{% highlight ruby %} +def deliver(from: "A", to: nil, via: "mail") + "Sending from #{from} to #{to} via #{via}." +end + +deliver(to: "B") +# => "Sending from A to B via mail." +deliver(via: "Pony Express", from: "B", to: "A") +# => "Sending from B to A via Pony Express." +{% endhighlight %} + +### Універсальна істина + +У Ruby усе, окрім `nil` і `false`, вважається істинним. У C, Python та +багатьох інших мовах 0 і, можливо, інші значення, як-от порожні списки, +вважаються хибними. Подивіться на такий код Python (цей приклад +застосовний і до інших мов): + +{% highlight python %} +# in Python +if 0: + print("0 is true") +else: + print("0 is false") +{% endhighlight %} + +Це виведе “0 is false”. Еквівалент у Ruby: + +{% highlight ruby %} +# in Ruby +if 0 + puts "0 is true" +else + puts "0 is false" +end +{% endhighlight %} + +Виводить “0 is true”. + +### Модифікатори доступу діють до кінця області видимості + +У наступному коді Ruby: + +{% highlight ruby %} +class MyClass + private + def a_method; true; end + def another_method; false; end +end +{% endhighlight %} + +Ви можете очікувати, що `another_method` буде публічним. Але ні. Модифікатор +доступу `private` діє до кінця області видимості або до наступного +модифікатора доступу — що настане раніше. За замовчуванням методи публічні: + +{% highlight ruby %} +class MyClass + # Now a_method is public + def a_method; true; end + + private + + # another_method is private + def another_method; false; end +end +{% endhighlight %} + +`public`, `private` і `protected` — це методи, тому вони можуть приймати +параметри. Якщо ви передасте символ, зміниться видимість відповідного методу. + +### Доступ до методів + +У Java `public` означає, що метод доступний будь-кому. `protected` +означає, що до нього можуть звертатися екземпляри класу, екземпляри +класів-нащадків і екземпляри класів у тому самому пакеті, але не інші. +`private` означає, що метод доступний лише екземплярам класу. + +У Ruby все трохи інакше. `public` — публічний. `private` означає, що +метод(и) доступні лише тоді, коли їх можна викликати без явного +одержувача. Єдиним дозволеним одержувачем приватного виклику є `self`. + +`protected` — це те, на що варто звернути увагу. Захищений метод можна +викликати з екземплярів класу або класів-нащадків, а також із іншим +екземпляром як одержувачем. +Ось приклад (адаптовано з [The Ruby Language FAQ][faq]): + +{% highlight ruby %} +class Test + # public by default + def identifier + 99 + end + + def ==(other) + identifier == other.identifier + end +end + +t1 = Test.new # => #+дата релізу: {{ branch.date }}
+звичайна підтримка до: {% if branch.security_maintenance_date %}{{ branch.security_maintenance_date }}{% else %}TBD{% endif %}
+EOL: {% if branch.eol_date %}{{ branch.eol_date }}{% else %}{% if branch.expected_eol_date %}{{ branch.expected_eol_date }} (очікується){% else %}TBD{% endif %}{% endif %} + +{% endfor %} diff --git a/ua/downloads/index.md b/ua/downloads/index.md new file mode 100644 index 0000000000..a180439549 --- /dev/null +++ b/ua/downloads/index.md @@ -0,0 +1,88 @@ +--- +layout: page +title: "Завантажити Ruby" +lang: ua +--- + +Тут ви можете отримати найсвіжіші дистрибутиви Ruby у зручному для вас форматі. +Поточна стабільна версія — {{ site.data.downloads.stable[0] }}. +Будь ласка, обов’язково прочитайте [ліцензію Ruby][license]. +{: .summary} + +### Способи встановлення Ruby + +Ми маємо кілька інструментів для кожної основної платформи: + +* На Linux/UNIX можна використовувати систему керування пакетами вашого + дистрибутива або сторонні інструменти ([rbenv][rbenv] і [RVM][rvm]). +* На macOS можна використовувати сторонні інструменти ([rbenv][rbenv] і [RVM][rvm]). +* На Windows можна використовувати [RubyInstaller][rubyinstaller]. + +Дивіться сторінку [Встановлення][installation] для деталей щодо використання +систем керування пакетами або сторонніх інструментів. + +Звісно, ви також можете встановити Ruby з вихідного коду на всіх основних платформах. + +### Компілювання Ruby — вихідний код + +Встановлення з вихідного коду — чудове рішення, коли ви добре орієнтуєтеся +у своїй платформі та, можливо, потребуєте специфічних налаштувань для +вашого середовища. Це також корисний варіант, якщо для вашої платформи +немає готових пакунків. + +Дивіться сторінку [Встановлення][installation] для деталей щодо збирання +Ruby з вихідного коду. Якщо у вас виникають проблеми з компіляцією Ruby, +розгляньте можливість використання одного зі згаданих вище сторонніх +інструментів — вони можуть допомогти. + +* **Стабільні релізи:**{% for version in site.data.downloads.stable %}{% assign release = site.data.releases | where: "version", version | first %} + * [Ruby {{ release.version }}]({{ release.url.gz }})
+ sha256: {{ release.sha256.gz }}{% endfor %} + +{% if site.data.downloads.preview %} +* **Попередні релізи:**{% for version in site.data.downloads.preview %}{% assign release = site.data.releases | where: "version", version | first %} + * [Ruby {{ release.version }}]({{ release.url.gz }})
+ sha256: {{ release.sha256.gz }}{% endfor %} +{% endif %} + +{% if site.data.downloads.security_maintenance %} +* **Фаза security maintenance (скоро EOL):**{% for version in site.data.downloads.security_maintenance %}{% assign release = site.data.releases | where: "version", version | first %} + * [Ruby {{ release.version }}]({{ release.url.gz }})
+ sha256: {{ release.sha256.gz }}{% endfor %} +{% endif %} + +{% if site.data.downloads.eol %} +* **Більше не підтримується (EOL):**{% for version in site.data.downloads.eol %}{% assign release = site.data.releases | where: "version", version | first %} + * [Ruby {{ release.version }}]({{ release.url.gz }})
+ sha256: {{ release.sha256.gz }}{% endfor %} +{% endif %} + +* **Снапшоти:**{% for snapshot in site.data.downloads.stable_snapshots %} + * [Стабільний снапшот гілки {{ snapshot.branch }}]({{ snapshot.url.gz }}): + Це tarball із найновішим снапшотом поточної гілки `{{ snapshot.branch }}`.{% endfor %} + * [Нічний снапшот]({{ site.data.downloads.nightly_snapshot.url.gz }}): + Це tarball з тим, що є в Git, сформований щоночі. + Він може містити помилки або інші проблеми — використовуйте на власний ризик! + +Для детальнішої інформації про конкретні релізи, особливо старіші або +попередні, дивіться сторінку [Релізи][releases]. +Інформацію про поточний статус підтримки різних гілок Ruby можна знайти +на сторінці [Гілки][branches]. + +Для інформації про репозиторії Ruby у Subversion та Git дивіться сторінку +[Ruby Core](/ua/community/ruby-core/). + +Вихідний код Ruby доступний через глобальний набір +[дзеркальних сайтів][mirrors]. +Будь ласка, намагайтеся використовувати дзеркало, що знаходиться ближче до вас. + + + +[license]: /ua/about/license.txt +[installation]: /ua/documentation/installation/ +[releases]: /ua/downloads/releases/ +[branches]: /ua/downloads/branches/ +[mirrors]: /ua/downloads/mirrors/ +[rvm]: http://rvm.io/ +[rbenv]: https://github.com/rbenv/rbenv +[rubyinstaller]: https://rubyinstaller.org/ diff --git a/ua/downloads/mirrors/index.md b/ua/downloads/mirrors/index.md new file mode 100644 index 0000000000..df09053704 --- /dev/null +++ b/ua/downloads/mirrors/index.md @@ -0,0 +1,49 @@ +--- +layout: page +title: "Дзеркальні сайти" +lang: ua +--- + +{% comment %} +Not to be translated. Link to this page (/en/downloads/mirrors/) instead. +{% endcomment %} + +Вихідний код Ruby доступний через набір дзеркальних сайтів по всьому світу. +Будь ласка, намагайтеся використовувати дзеркало, що знаходиться ближче до вас. +{: .summary} + +### Дзеркальні сайти через HTTP + +* [CDN][mirror-https-cdn] (fastly.com) +* [Японія][mirror-http-jp-ring] (RingServer) +* [Нідерланди][mirror-http-nl] (XS4ALL) - лише пакунки релізів +* [Франція][mirror-http-fr] (cyberbits.eu) +* [Китай 2][mirror-http-cn2] (Ruby China) +* [Південна Корея][mirror-http-kr] (Korea FreeBSD Users Group) + +### Дзеркальні сайти через FTP + +* [Японія][mirror-ftp-jp-ring] (RingServer) +* [Японія 3][mirror-ftp-jp3] (IIJ) +* [Південна Корея][mirror-ftp-kr] (Korea FreeBSD Users Group) +* [Німеччина][mirror-ftp-de] (FU Berlin) +* [Греція][mirror-ftp-gr] (ntua.gr) + +### Дзеркальні сайти через rsync + +* [Франція][mirror-rsync-fr] (cyberbits.eu) +* [Південна Корея][mirror-rsync-kr] (Korea FreeBSD Users Group) + +[mirror-https-cdn]: https://cache.ruby-lang.org/pub/ruby/ +[mirror-http-jp-ring]: http://www.ring.gr.jp/pub/lang/ruby/ +[mirror-http-nl]: http://www.xs4all.nl/~hipster/lib/mirror/ruby/ +[mirror-http-fr]: https://mirror.cyberbits.eu/ruby/ +[mirror-http-cn2]: https://cache.ruby-china.com/pub/ruby/ +[mirror-http-kr]: http://ftp.kr.freebsd.org/pub/ruby/ +[mirror-ftp-jp-ring]: ftp://ftp.ring.gr.jp/pub/lang/ruby/ +[mirror-ftp-jp3]: ftp://ftp.iij.ad.jp/pub/lang/ruby/ +[mirror-ftp-kr]: ftp://ftp.kr.freebsd.org/pub/ruby/ +[mirror-ftp-de]: ftp://ftp.fu-berlin.de/unix/languages/ruby/ +[mirror-ftp-gr]: ftp://ftp.ntua.gr/pub/lang/ruby/ +[mirror-rsync-fr]: rsync://rsync.cyberbits.eu/ruby/ +[mirror-rsync-kr]: rsync://rsync.kr.freebsd.org/ruby/ diff --git a/ua/downloads/releases/index.md b/ua/downloads/releases/index.md new file mode 100644 index 0000000000..91dffb2046 --- /dev/null +++ b/ua/downloads/releases/index.md @@ -0,0 +1,35 @@ +--- +layout: page +title: "Релізи Ruby" +lang: ua +--- + +На цій сторінці наведені окремі релізи Ruby. +{: .summary} + +Інформацію про поточний статус підтримки різних гілок Ruby дивіться на +[сторінці гілок](../branches/). + +### Релізи Ruby за номером версії + +Це список релізів Ruby. +Показані дати відповідають датам публікації англомовних +публікацій про релізи й можуть відрізнятися від фактичних +дат створення вихідних tarball-ів. + +
| Версія релізу | +Дата релізу | +URL для завантаження | +Нотатки до релізу | +
|---|---|---|---|
| Ruby {{ release.version }} | +{{ release.date }} | +завантажити | +детальніше... | +
+
+З [бенчмарком Optcarrot](https://github.com/mame/optcarrot), який вимірює однопотокову продуктивність на основі емуляції ігор NES, він досяг у 3 рази кращої продуктивності, ніж Ruby 2.0!
+
+## Логотип
+
+[Логотип Ruby][logo] захищений авторським правом © 2006, Yukihiro Matsumoto.
+
+
+## Повідомлення про проблеми ##
+
+Щоб повідомити про проблему, використовуйте [issue tracker][github-issues]
+або зверніться до нашого [вебмайстра][webmaster] (англійською).
+
+
+## Як долучитися ##
+
+Цей вебсайт з гордістю підтримується членами спільноти Ruby.
+
+Якщо ви хочете зробити внесок, ознайомтеся з
+[інструкціями для учасників][github-wiki]
+і просто відкривайте issues або pull requests!
+
+
+## Подяки ##
+
+Дякуємо всім комітерам, авторам, перекладачам та іншим учасникам цього
+вебсайту.
+
+Також велика подяка організаціям, які нас підтримують:
+
+






