Приховані риси Рубі


160

Продовжуючи мем "Приховані особливості ...", поділимося менш відомими, але корисними особливостями мови програмування Ruby.

Спробуйте обмежити цю дискусію основними Ruby, без будь-яких матеріалів Ruby on Rails.

Дивитися також:

(Будь ласка, лише одна прихована функція за кожну відповідь.)

Дякую


повинні бути вікі спільноти
SilentGhost

Відповіді:


80

З Ruby 1.9 Proc # === - псевдонім Proc # call, що означає, що об'єкти Proc можуть використовуватися в таких випадках:

def multiple_of(factor)
  Proc.new{|product| product.modulo(factor).zero?}
end

case number
  when multiple_of(3)
    puts "Multiple of 3"
  when multiple_of(7)
    puts "Multiple of 7"
end

1
Я фактично написав дорогоцінний камінь в один момент, щоб це зробити, але мій код був (а) безлад і (б) повільний. Я дуже радий, що функціонал зробив це в основі.
Джеймс А. Росен

76

У Пітера Купера хороший список трюків Рубі. Можливо, мій улюблений з нього - це перерахування як окремих предметів, так і колекцій. (Тобто трактуйте об'єкт, що не збирає колекцію, як колекцію, що містить саме цей об'єкт.) Це виглядає приблизно так:

[*items].each do |item|
  # ...
end

38
Більш чіткою (і тим приємнішою) формою цього є Array (items) .each
mislav

Якщо itemsце рядок, вам не доведеться додавати його до [*…]. String.each не перебирає символи, як дехто може очікувати. Він просто повертається до блоку.
mxcl

Якої користі це коли-небудь послужило б? Просто цікаво.
Ед С.

1
@Ed: приємно, якщо ви пишете метод і хочете дозволити користувачу методу або передати список varargs, або Array.
Джеймс А. Росен

64

Не знаю, наскільки це приховано, але я вважаю це корисним, коли потрібно зробити хеш із одновимірного масиву:

fruit = ["apple","red","banana","yellow"]
=> ["apple", "red", "banana", "yellow"]

Hash[*fruit]    
=> {"apple"=>"red", "banana"=>"yellow"}

Зверніть увагу, що Hash[ [["apple","red"], ["banana","yellow"] ]дає такий же результат.
Марк-Андре Лафортун

54

Мені подобається один фокус - використовувати *розширювач splat ( ) для інших об'єктів, крім масивів. Ось приклад регулярного збігу виразів:

match, text, number = *"Something 981".match(/([A-z]*) ([0-9]*)/)

Інші приклади включають:

a, b, c = *('A'..'Z')

Job = Struct.new(:name, :occupation)
tom = Job.new("Tom", "Developer")
name, occupation = *tom

13
До речі, для допитливих це спрацьовує, неявно викликаючи to_a на ціль бризки.
Боб Аман

1
Якщо ви не зацікавлені в матчі, ви можете мати text, number = *"text 555".match(/regexp/)[1..-1].
Ендрю Грімм

text, number = "Something 981".scan(/([A-z]*) ([0-9]*)/).flatten.map{|m| Integer(m) rescue m}
Йонас Ельфстрем

7
Обидва хороші хитрощі, але має бути момент, коли це занадто багато магії, правда ?!
tomafro

1
@Andrew, ти вважав, що цей матч може повернути нуль? nil не має методу []
Олексій

52

Нічого ж, ніхто не згадав оператора фліп-флопу:

1.upto(100) do |i|
  puts i if (i == 3)..(i == 15)
end

11
Правильно ... хтось повинен буде мені це пояснити. Це працює, але я не можу зрозуміти, чому.
Боб Аман

12
Оператор фліп-флопу - це стан, якщо це можливо. Його стан переходить до істинного, як тільки, i == 3і переходить у хибне після i != 3 і i == 15. Схожий на триггер: en.wikipedia.org/wiki/Flip-flop_%28electronics%29
Костянтин Хааз

1
Я б точно не назвав це прихованою особливістю, настільки роздратування. Я пам’ятаю перший раз, коли мене познайомили з ним у #Ruby на Freenode, років тому; Я в основному використовував кожну функцію Ruby в якийсь момент, крім цієї.
ELLIOTTCABLE

1
Я б не називав це роздратуванням, це просто те, що ви не використовували. Я використовую його, і він може добре зменшити код, особливо коли я захоплюю блоки рядків з файлів на основі деяких критеріїв.
Олов'яний чоловік

49

Однією із цікавих речей у рубіні є те, що ви можете викликати методи та запускати код у місцях, де інші мови нахмурилися б, наприклад, у визначеннях методу чи класу.

Наприклад, щоб створити клас, який має невідомий надклас до часу виконання, тобто випадковий, ви можете зробити наступне:

class RandomSubclass < [Array, Hash, String, Fixnum, Float, TrueClass].sample

end

RandomSubclass.superclass # could output one of 6 different classes.

Для цього використовується Array#sampleметод 1.9 (див. Лише в 1.8.7 Array#choice), і приклад досить надуманий, але ви можете бачити потужність тут.

Ще один класний приклад - можливість встановлювати значення параметрів за замовчуванням, які не є фіксованими (як це часто вимагають інші мови):

def do_something_at(something, at = Time.now)
   # ...
end

Звичайно, проблема першого прикладу полягає в тому, що він оцінюється під час визначення, а не час виклику. Отже, після обрання суперкласу він залишається таким суперкласом для решти програми.

Однак у другому прикладі кожного разу, коли ви викликаєте do_something_at, atзмінна буде тим часом, в якому викликався метод (ну, дуже близький до нього)


2
Примітка: масив # rand надається ActiveSupport, який ви можете використовувати поза межами Rails так само легко, якrequire 'activesupport'
rfunduk

Вибір масиву №1 - в 1.8.7
Джош Лі

24
Вибір масиву №1 - лише 1.8.7 ! Не використовуйте його, він закінчився в 1.9 і піде в 1.8.8. Використовуйте #sample
Marc-André Lafortune

python: клас DictList ([dict, list] [random.randint (0,1)]): pass
Anurag Uniyal

def do_something_at (щось, в = лямбда {Time.now}) at.call #now динамічно призначити кінець часу
Джек Кінселла

47

Ще одна крихітна особливість - перетворення Fixnumв будь-яку базу до 36:

>> 1234567890.to_s(2)
=> "1001001100101100000001011010010"

>> 1234567890.to_s(8)
=> "11145401322"

>> 1234567890.to_s(16)
=> "499602d2"

>> 1234567890.to_s(24)
=> "6b1230i"

>> 1234567890.to_s(36)
=> "kf12oi"

І як прокоментував Х'ю Уолтерс, перетворення іншого способу так само просто:

>> "kf12oi".to_i(36)
=> 1234567890

1
А для повноти String#to_s(base)може використовуватися для перетворення назад у ціле число; "1001001100101100000001011010010".to_i(2), І "499602d2".to_i(16)т.д. все повернення оригіналу Fixnum.
Хью Уолтерс

40

Хеши з типовими значеннями! Масив у цьому випадку.

parties = Hash.new {|hash, key| hash[key] = [] }
parties["Summer party"]
# => []

parties["Summer party"] << "Joe"
parties["Other party"] << "Jane"

Дуже корисний при метапрограмуванні.


1
так правда. Ruby хеш може прийняти оператор "<<", якщо вже вказане значення за замовчуванням присвоїти '=' (байдуже, навіть якщо це порожнє призначення), інакше хеш не прийме "<<". CMIIW
mhd

39

Завантажте джерело Ruby 1.9 і видайте make golf, тоді ви можете робити такі дії:

make golf

./goruby -e 'h'
# => Hello, world!

./goruby -e 'p St'
# => StandardError

./goruby -e 'p 1.tf'
# => 1.0

./goruby19 -e 'p Fil.exp(".")'
"/home/manveru/pkgbuilds/ruby-svn/src/trunk"

Прочитайте golf_prelude.cдетальніші речі, які ховаються.


38

Ще одне цікаве доповнення у функціональності 1.9 Proc - це Proc # curry, який дозволяє перетворити Proc, що приймає n аргументів, у той, що приймає n-1. Тут він поєднується з порадою Proc # ===, яку я згадав вище:

it_is_day_of_week = lambda{ |day_of_week, date| date.wday == day_of_week }
it_is_saturday = it_is_day_of_week.curry[6]
it_is_sunday = it_is_day_of_week.curry[0]

case Time.now
when it_is_saturday
  puts "Saturday!"
when it_is_sunday
  puts "Sunday!"
else
  puts "Not the weekend"
end

35

Булі оператори на не булеві значення.

&& і ||

Обидва повертають значення останнього оціненого виразу.

Ось чому ||=воля оновить змінну зі значенням, що повертається виразом праворуч, якщо змінна не визначена. Це не явно задокументоване, а загальновідоме.

Однак про &&=це не так широко відомо.

string &&= string + "suffix"

еквівалентно

if string
  string = string + "suffix"
end

Це дуже зручно для руйнівних операцій, які не повинні тривати, якщо змінна не визначена.


2
Точніше, string &&= string + "suffix" рівнозначно string = string && string + "suffix". Це &&та ||повернення їх другого аргументу обговорюється в PickAx, p. 154 (частина I - грані рубіну, вирази, умовне виконання).
Річард Майкл

29

Функція Symbol # to_proc, яку надає Rails, справді класна.

Замість

Employee.collect { |emp| emp.name }

Ви можете написати:

Employee.collect(&:name)

Це, мабуть, "на порядок повільніше", ніж використання блоку. igvita.com/2008/07/08/6-optimization-tips-for-ruby-mri
Чарльз Ропер

Я просто спробував це, і виявив, що між ними немає суттєвої різниці. Я не впевнений, звідки взявся цей "порядок величини". (Використовуючи Ruby 1.8.7)
Matt Grande

1
Робити це за межами Rails також зручно, і це можна зробити, require 'activesupport'оскільки саме звідси походить більшість цих помічників.
rfunduk

8
це було повільним через реалізацію active_support, тобто він приймав кілька аргументів, щоб ви могли робити круті лайни на зразок (1..10) .inject &: *, але основний випадок використання часто був лише викликом методу для кожного члена а колекція, наприклад,% w (швидка бура лисиця). map &: upcase. станом на 1.8.7 - це основний рубін та ефективність.
Стів Грехем,

4
@thenduks: І це можна зробити без допомоги активістів у рубінах 1.8.7 та 1.9.
Ендрю Грімм

28

Останнє - в рубіні ви можете використовувати будь-який символ, який ви хочете розмежувати. Візьміть наступний код:

message = "My message"
contrived_example = "<div id=\"contrived\">#{message}</div>"

Якщо ви не хочете уникати подвійних лапок в рядку, ви можете просто використовувати інший роздільник:

contrived_example = %{<div id="contrived-example">#{message}</div>}
contrived_example = %[<div id="contrived-example">#{message}</div>]

Окрім уникнення необхідності уникнути розмежувачів, ви можете використовувати ці роздільники для кращих багаторядкових рядків:

sql = %{
    SELECT strings 
    FROM complicated_table
    WHERE complicated_condition = '1'
}

19
не будь-який персонаж, але все одно досить круто. Він також працює з іншими літералами:% () /% {} /% [] /% <> /% || % r () /% r {} /% r [] /% r <> /% r || % w () /% w {} /% w [] /% w <> /% w ||
Bo Jeanes

Є також синтаксис donow doc: << БЛОК… БЛОК, який я люблю використовувати для таких речей, як багаторядкові заяви SQL тощо.
Мартін Т.

26

Я вважаю, що використання команди define_method для динамічного генерування методів є досить цікавим і не так відомим. Наприклад:

((0..9).each do |n|
    define_method "press_#{n}" do
      @number = @number.to_i * 10 + n
    end
  end

Вищевказаний код використовує команду 'define_method' для динамічного створення методів «press1» через «press9». Замість того, щоб набрати всі 10 методів, які в основному містять один і той же код, команда define метод використовується для створення цих методів на льоту, за необхідності.


4
Єдина проблема з define_method полягає в тому, що він не дозволяє блокам передаватись як параметри в рубіні 1.8. Дивіться цю публікацію в блозі для вирішення проблеми.
Ендрю Грімм

26

Використовуйте об’єкт Range як нескінченний лінивий список:

Inf = 1.0 / 0

(1..Inf).take(5) #=> [1, 2, 3, 4, 5]

Більше інформації тут: http://banisterfiend.wordpress.com/2009/10/02/wtf-infinite-ranges-in-ruby/


Lazy_select у пов’язаній статті дуже акуратний.
Джозеф Вайсман

Це справді приголомшливо. Мені подобається, як Infinity є плаваючою ланкою, саме так, коли я спробував це: (-Inf..Inf) .take (4) він підняв (логічно послідовний), не може ітератувати з помилкою float. : D
зачаян

23

модуль_функція

Методи модуля, оголошені як module_function , створюватимуть копії себе як приватні методи екземпляра в класі, що включає модуль:

module M
  def not!
    'not!'
  end
  module_function :not!
end

class C
  include M

  def fun
    not!
  end
end

M.not!     # => 'not!
C.new.fun  # => 'not!'
C.new.not! # => NoMethodError: private method `not!' called for #<C:0x1261a00>

Якщо ви використовуєте module_function без будь-яких аргументів, то будь-які методи модуля, що з’являються після оператора module_function, автоматично стануть самими module_functions.

module M
  module_function

  def not!
    'not!'
  end

  def yea!
    'yea!'
  end
end


class C
  include M

  def fun
    not! + ' ' + yea!
  end
end
M.not!     # => 'not!'
M.yea!     # => 'yea!'
C.new.fun  # => 'not! yea!'

4
Якщо ви просто хочете оголосити приватні методи в модулях, просто використовуйте приватне ключове слово. На додаток до методу приватним у класах, що включають модуль, module_function копіює метод в екземпляр модуля. У більшості випадків це не те, що ви хочете.
tomafro

Я знаю, що ви можете просто використовувати приватне. Але це питання про приховані риси Рубі. І, я думаю, більшість людей ніколи не чули про модульну функцію (включаючи і мене), поки не побачать її в документі і не почнуть із нею грати.
newtonapple

Альтернативою використанню module_function(другий спосіб) є просто використання extend self(що виглядає досить приємно: D)
J -_- L


21

Попередження: за цей пункт проголосували №1 за найжахливіший хак 2008 року , тому використовуйте обережно. Насправді уникайте цього, як чуми, але це, звичайно, прихований Рубі.

Суператори Додають нових операторів до Ruby

Коли-небудь хочете суперсекретного оператора рукостискання для унікальної операції у вашому коді? Як грати в гольф-код? Спробуйте такі оператори, як - ~ + ~ - або <--- Цей останній використовується в прикладах для зміни порядку порядку елемента.

Я не маю нічого спільного з проектом Superators, окрім захоплення ним.


19

Я спізнююсь на вечірку, але:

Ви можете легко взяти два масиви однакової довжини і перетворити їх у хеш з одним масивом, що подає ключі, а іншим значення:

a = [:x, :y, :z]
b = [123, 456, 789]

Hash[a.zip(b)]
# => { :x => 123, :y => 456, :z => 789 }

(Це працює, тому що масив # zip "перескакує" значення з двох масивів:

a.zip(b)  # => [[:x, 123], [:y, 456], [:z, 789]]

І Hash [] може взяти саме такий масив. Я бачив, як це роблять і люди:

Hash[*a.zip(b).flatten]  # unnecessary!

Що дає такий самий результат, але плескіт і сплющення зовсім не потрібні - можливо, вони не були в минулому?)


3
Це довгий час було справді недокументовано (див. Redmine.ruby-lang.org/isissue/show/1385 ). Зауважте, що ця нова форма є новою для Ruby 1.8.7
Marc-André Lafortune

19

Автовізуючі хеші в Ruby

def cnh # silly name "create nested hash"
  Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}
end
my_hash = cnh
my_hash[1][2][3] = 4
my_hash # => { 1 => { 2 => { 3 =>4 } } }

Це просто може бути проклято.


1
Я б загорнув його в модуль, щоб мати таке відчуття, як рідний хеш-ініт: module InfHash; def self.new; Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}; end; end
ініт

16

Знищення масиву

(a, b), c, d = [ [:a, :b ], :c, [:d1, :d2] ]

Де:

a #=> :a
b #=> :b
c #=> :c
d #=> [:d1, :d2]

За допомогою цієї методики ми можемо використовувати просте завдання, щоб отримати точні значення, які ми хочемо, із вкладеного масиву будь-якої глибини.


15

Class.new()

Створіть новий клас під час виконання. Аргументом може бути клас, похідний від якого, а блок - це клас класу. Ви також можете поглянути на те, const_set/const_get/const_defined?щоб ваш новий клас був належним чином зареєстрований, щоб він inspectвиводив ім'я замість числа.

Не те, що вам потрібно щодня, але досить зручно, коли ви це робите.


1
MyClass = Class.new Array do; def hi; 'hi'; end; endначебто рівнозначно class MyClass < Array; def hi; 'hi'; end; end.
yfeldblum

1
Напевно, правдивіше, ніж я думав. Здається навіть, що ви можете успадкувати змінну, а не лише константу. Однак видана версія (друга) не працює, якщо вам потрібно побудувати ім'я класу під час виконання. (Барінг еваль, звичайно.)
Джастін Любов

Ця методика досить добре описана в книзі Метапрограмування Ruby .
Пол Пладійс

13

створити масив послідовних чисел:

x = [*0..5]

задає х на [0, 1, 2, 3, 4, 5]


Так, але це не так коротко і солодко;)
horseyguy

2
лаконічність об’єктивна, читабельність - справа смаку та досвіду
Олексій

Оператор splat ( *) в основному to_aвсе-таки дзвонить .
Матей Морейра

13

Багато магії, яку ви бачите в Rubyland, пов'язана з метапрограмуванням, це просто написання коду, який пише код для вас. Ruby's attr_accessor, attr_readerі attr_writerвсі це просте метапрограмування, оскільки вони створюють два методи в одному рядку, дотримуючись стандартного зразка. Rails робить багато метапрограмування за допомогою таких методів управління відносинами, як has_oneі belongs_to.

Але досить просто створити власні трюки з метапрограмуванням, використовуючи class_evalдля виконання динамічно записаного коду.

Наступний приклад дозволяє об’єкту обгортки пересилати певні методи разом із внутрішнім об'єктом:

class Wrapper
  attr_accessor :internal

  def self.forwards(*methods)
    methods.each do |method|
      define_method method do |*arguments, &block|
        internal.send method, *arguments, &block
      end
    end
  end

  forwards :to_i, :length, :split
end

w = Wrapper.new
w.internal = "12 13 14"
w.to_i        # => 12
w.length      # => 8
w.split('1')  # => ["", "2 ", "3 ", "4"]

Метод Wrapper.forwardsбере символи для назв методів і зберігає їх у methodsмасиві. Потім, для кожного з цих, ми використовуємоdefine_method для створення нового методу, завданням якого є надсилання повідомлення разом, включаючи всі аргументи та блоки.

Чудовим ресурсом для питань метапрограмування є Чому "Бачити метапрограмування чітко" Лакі Стіффа .


Я б хотів спочатку зануритися в метапрограмування в рубіні. Чи можете ви надати деякі посилання, щоб розпочати роботу (крім вказаного посилання)? Книги теж будуть робити. Дякую.
Чирантан

Відео-трансляція серії PragProg "Модель об'єкта Ruby та метапрограмування" - це гарне введення у метапрограмування за допомогою ruby: pragprog.com/screencasts/v-dtrubyom/…
caffo

@Chirantan, подивіться на Metaprogramming Ruby .
Пол Пладійс

12

використовувати будь-що, що відповідає ===(obj)для порівняння випадків:

case foo
when /baz/
  do_something_with_the_string_matching_baz
when 12..15
  do_something_with_the_integer_between_12_and_15
when lambda { |x| x % 5 == 0 }
  # only works in Ruby 1.9 or if you alias Proc#call as Proc#===
  do_something_with_the_integer_that_is_a_multiple_of_5
when Bar
  do_something_with_the_instance_of_Bar
when some_object
  do_something_with_the_thing_that_matches_some_object
end

Module(і таким чином Class) Regexp,Date , і багато інших класи визначають метод примірника: === (інший), і все вони можуть бути використані.

Дякую Фаррелу за нагадування про Proc#callте, що він відчужений як Proc#===у Ruby 1.9.


11

Бінарний "рубін" (принаймні МРТ) підтримує безліч комутаторів, які зробили однокласикові перли досить популярними.

Важливі:

  • -n Встановлює зовнішній цикл із просто "отримує" - який магічно працює з заданим іменем файлу або STDIN, встановлюючи кожен рядок читання у $ _
  • -p Подібно до -n, але з автоматичним puts в кінці кожної циклу ітерації
  • -автоматичний виклик на .split на кожному вхідному рядку, що зберігається у $ F
  • -i на місці редагування вхідних файлів
  • -l Автоматичний дзвінок на .chomp на вході
  • -e Виконати фрагмент коду
  • -c Перевірте вихідний код
  • -w З попередженнями

Деякі приклади:

# Print each line with its number:
ruby -ne 'print($., ": ", $_)' < /etc/irbrc

# Print each line reversed:
ruby -lne 'puts $_.reverse' < /etc/irbrc

# Print the second column from an input CSV (dumb - no balanced quote support etc):
ruby -F, -ane 'puts $F[1]' < /etc/irbrc

# Print lines that contain "eat"
ruby -ne 'puts $_ if /eat/i' < /etc/irbrc

# Same as above:
ruby -pe 'next unless /eat/i' < /etc/irbrc

# Pass-through (like cat, but with possible line-end munging):
ruby -p -e '' < /etc/irbrc

# Uppercase all input:
ruby -p -e '$_.upcase!' < /etc/irbrc

# Same as above, but actually write to the input file, and make a backup first with extension .bak - Notice that inplace edit REQUIRES input files, not an input STDIN:
ruby -i.bak -p -e '$_.upcase!' /etc/irbrc

Не соромтеся гугл "рубінові однолінійки" та "перл однолінійки" на тонни більш зручних та практичних прикладів. Це по суті дозволяє використовувати рубін як досить потужну заміну на awk і sed.


10

Метод send () - це метод загального призначення, який можна використовувати в будь-якому класі або об'єкті в Ruby. Якщо це не буде замінено, send () приймає рядок і називає ім'я методу, рядок якого він переданий. Наприклад, якщо користувач натискає кнопку "Clr", рядок "press_clear" буде надісланий методом send (), а метод "press_clear" буде викликаний. Метод send () дозволяє отримати цікавий та динамічний спосіб виклику функцій у Ruby.

 %w(7 8 9 / 4 5 6 * 1 2 3 - 0 Clr = +).each do |btn|
    button btn, :width => 46, :height => 46 do
      method = case btn
        when /[0-9]/: 'press_'+btn
        when 'Clr': 'press_clear'
        when '=': 'press_equals'
        when '+': 'press_add'
        when '-': 'press_sub'
        when '*': 'press_times'
        when '/': 'press_div'
      end

      number.send(method)
      number_field.replace strong(number)
    end
  end

Я детальніше розповідаю про цю функцію в Blogging Shoes: Проста програма Calc


Звучить чудовим способом відкрити отвір для захисту.
мП.

4
Я б використовував символи, коли це можливо.
рето

9

Обдуріть якийсь клас або модуль, який говорить, що йому потрібно щось, чого він насправді не вимагає:

$" << "something"

Це корисно, наприклад, коли потрібен A, який по черзі вимагає B, але нам не потрібен B в нашому коді (і A не буде використовувати його ні через наш код):

Наприклад, Backgroundrb bdrb_test_helper requires 'test/spec', але ви його взагалі не використовуєте, тому у своєму коді:

$" << "test/spec"
require File.join(File.dirname(__FILE__) + "/../bdrb_test_helper")

Чи виправляє це проблеми, коли для gem A потрібен foo-1.0.0, а для gem B потрібен foo-1.0.1?
Ендрю Грімм

Ні, тому що код "чогось" буде недоступний: це лише імітує, що "щось" потрібно, але це дійсно цього не вимагає. $ "- це масив, що містить імена модулів, завантажені на вимогу (він використовується вимогою, щоб запобігти завантаженню модулів двічі). Отже, якщо ви використовуєте це для того, щоб обдурити дорогоцінні камені, це призведе до збою, коли дорогоцінні камені намагаються використовувати фактичне" щось " код, тому що його не буде. Натомість ви можете захотіти примусово застосовувати конкретні версії самоцвіту (наприклад, foo-1.0.0) замість останньої: docs.rubygems.org/read/chapter/4#page71
олегерет

9

Fixnum#to_s(base)може бути дуже корисним у деяких випадках. Один з таких випадків - генерування випадкових (псевдо) унікальних лексем шляхом перетворення випадкового числа в рядок, використовуючи базу 36.

Маркер довжиною 8:

rand(36**8).to_s(36) => "fmhpjfao"
rand(36**8).to_s(36) => "gcer9ecu"
rand(36**8).to_s(36) => "krpm0h9r"

Маркер довжиною 6:

rand(36**6).to_s(36) => "bvhl8d"
rand(36**6).to_s(36) => "lb7tis"
rand(36**6).to_s(36) => "ibwgeh"

9

Визначення методу, який приймає будь-яку кількість параметрів і просто відкидає їх усі

def hello(*)
    super
    puts "hello!"
end

Вищеописаний helloметод потребує лише puts "hello"на екрані та виклику, superале оскільки суперклас helloвизначає параметри, які він повинен робити, проте, оскільки він фактично не потребує використання самих параметрів - не потрібно давати їм ім'я.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.