Скрытые возможности Ruby

160

Продолжая тему «Скрытые возможности ...», давайте расскажем о менее известных, но полезных функциях языка программирования Ruby.

Попытайтесь ограничить это обсуждение ядром Ruby, без каких-либо вещей Ruby on Rails.

Смотрите также:

(Пожалуйста, только одна скрытая функция в ответ.)

Спасибо

эскадрон
источник
должно быть сообщество вики
SilentGhost

Ответы:

80

Начиная с Ruby 1.9, Proc # === является псевдонимом вызова Proc #, что означает, что объекты Proc могут использоваться в выражениях case следующим образом:

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
Farrel
источник
1
Я на самом деле написал для этого гем, но мой код был (а) беспорядочным и (б) медленным. Я очень рад, что функциональность превратила его в ядро.
Джеймс А. Розен
76

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

[*items].each do |item|
  # ...
end
Джеймс А. Розен
источник
38
Более явной (и, следовательно, более приятной) формой этого является Array (items) .each
mislav
Если itemsэто строка, вам не нужно заключать ее в [*…]. String.each не выполняет итерации по символам, как некоторые могут ожидать. Он просто возвращает себя в блок.
mxcl
Какая польза от этого? Просто любопытно.
Эд С.
1
@Ed: хорошо, если вы пишете метод и хотите, чтобы пользователь метода пропустил список varargs или массив.
Джеймс А. Розен
64

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

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

Hash[*fruit]    
=> {"apple"=>"red", "banana"=>"yellow"}
astronautism
источник
Обратите внимание, что 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
tomafro
источник
13
Между прочим, для любопытных это работает, неявно вызывая to_a для цели splat.
Боб Аман
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
Оба хороших трюка, но должен быть момент, когда в нем слишком много магии, верно ?!
Томафро
1
@ Андрей, ты считал, что матч может вернуть ноль? у ноля нет метода []
Алексей
52

Вау, никто не упомянул оператор триггера:

1.upto(100) do |i|
  puts i if (i == 3)..(i == 15)
end
Константин Хаазе
источник
11
Правильно ... кому-то придется объяснить это мне. Это работает, но я не могу понять, почему.
Боб Аман
12
Оператор триггера является Statefull, если. Его состояние переключается на true, как только, i == 3и переключается на false после i != 3 и i == 15. Похоже на триггер: en.wikipedia.org/wiki/Flip-flop_%28electronics%29
Константин Хаазе
1
Я бы точно не назвал это скрытой функцией, так много раздражения. Я помню, как впервые познакомился с ним в #Ruby на Freenode много лет назад; В какой-то момент я использовал практически все функции Ruby, кроме этой.
ELLIOTTCABLE
1
Я бы не назвал это раздражением, это просто то, что вы не использовали. Я использую его, и он может хорошо сократить код, особенно когда я беру блоки строк из файлов на основе некоторых критериев.
Жестянщик
49

Одна из замечательных особенностей ruby ​​заключается в том, что вы можете вызывать методы и выполнять код в тех местах, где другие языки будут недовольны, например, в определениях методов или классов.

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

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переменная будет время , что метод был назван (ну, очень и очень близко к нему)

bjeanes
источник
2
Примечание: Массив # rand предоставляется ActiveSupport, который вы можете использовать вне Rails так же легко, какrequire 'activesupport'
rfunduk
Выбор массива # в 1.8.7
Джош Ли
24
Выбор массива № 1.8.7 только ! Не используйте его, он вышел в 1.9 и будет в 1.8.8. Используйте #sample
Марк-Андре Лафортун
python: класс DictList ([dict, list] [random.randint (0,1)]): pass
Anurag Uniyal
def do_something_at (что-то, at = lambda {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
tomafro
источник
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
Да, верно. Рубиновый хеш может принять оператор «<<», если уже есть значение по умолчанию, назначенное с помощью «=» (не важно, пустое ли это назначение), в противном случае хэш не примет «<<». 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для более аккуратных вещей, скрывающихся.

Manveru
источник
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

Это очень удобно для деструктивных операций, которые не должны продолжаться, если переменная не определена.

EmFi
источник
2
Точнее, string &&= string + "suffix" эквивалентно string = string && string + "suffix". Это &&и ||возвращение их второй аргумент обсуждается в PickAx, с. 154 (часть I - аспекты Ruby, выражения, условное выполнение).
Ричард Майкл
29

Функция Symbol # to_proc, которую предоставляет Rails, действительно классная.

Вместо того

Employee.collect { |emp| emp.name }

Ты можешь написать:

Employee.collect(&:name)
hoyhoy
источник
Это, по-видимому, «на порядок медленнее», чем использование блока. igvita.com/2008/07/08/6-optimization-tips-for-ruby-mri
Чарльз Ропер,
Я только что попробовал, и обнаружил, что между ними нет существенной разницы. Я не уверен, откуда взялись эти "порядки". (Использование Ruby 1.8.7)
Мэтт Гранде,
1
Делать это вне Rails также удобно и может быть сделано, require 'activesupport'потому что именно отсюда большинство этих помощников.
rfunduk
8
Раньше это было медленно из-за реализации active_support, то есть он принимал несколько аргументов, так что вы могли делать крутое дерьмо, как (1..10) .inject &: *, но основным вариантом использования часто был только вызов метода для каждого члена коллекция, например,% w (быстрая коричневая лиса) .map &: upcase. по состоянию на 1.8.7 это ядро ​​рубина и производительность приемлемая.
Стив Грэм
4
@thenduks: И это можно сделать без помощи activesupport в ruby ​​1.8.7 и 1.9.
Эндрю Гримм
28

И последнее: в ruby ​​вы можете использовать любой символ, который хотите разделить. Возьмите следующий код:

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'
}
tomafro
источник
19
не какой-нибудь персонаж, но все равно довольно круто. Он также работает с другими литералами:% () /% {} /% [] /% <> /% || % r () /% r {} /% r [] /% r <> /% r || % w () /% w {} /% w [] /% w <> /% w ||
Бо Жанес
Существует также синтаксис документа herenow doc: << BLOCK ... BLOCK, который мне нравится использовать для таких вещей, как многострочные операторы SQL и т. Д.
Martin T.
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 method используется для генерации этих методов на лету по мере необходимости.

оборота CodingWithoutComments
источник
4
Единственная проблема с define_method заключается в том, что он не позволяет передавать блоки в качестве параметров в ruby ​​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/

horseyguy
источник
Lazy_select в связанной статье очень аккуратный.
Джозеф Вайсман
Это действительно круто. Мне нравится, что Infinity - это число с плавающей точкой, поэтому, когда я попробовал это: (-Inf..Inf) .take (4), он поднял (логически непротиворечиво) не может повторить ошибку float. : D
zachaysan
23

module_function

Методы модуля, которые объявлены как 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
Если вы просто хотите объявить приватные методы в модулях, просто используйте ключевое слово private. В дополнение к закрытому методу метода в классах, которые включают модуль, module_function копирует метод в экземпляр модуля. В большинстве случаев это не то, что вы хотите.
Tomafro
Я знаю, что вы можете просто использовать личное. Но это вопрос о скрытых возможностях Руби. И я думаю, что большинство людей никогда не слышали о module_function (включая меня), пока не увидят его в документе и не начнут с ним играть.
Newtonapple
Альтернатива использованию module_function(2-й способ) - просто использовать extend self(что выглядит довольно неплохо: D)
J -_- L
23

Коротко впрысните, вот так:

Сумма диапазона:

(1..10).inject(:+)
=> 55
user130730
источник
2
Стоит отметить, что для этого вам нужен Ruby 1.9 или Rails с Ruby 1.8.
mxcl
1
@ Макс Хауэлл: или require 'backports':-)
Марк-Андре Лафортун
1
Разве это не дубликат ответа Хойхоя?
Эндрю Гримм
21

Предупреждение: этот предмет был выбран # 1 Самый ужасный хак 2008 года , поэтому используйте его с осторожностью. На самом деле, избегайте этого, как чумы, но это, безусловно, скрытый рубин.

Суператоры добавляют новых операторов в Ruby

Вы когда-нибудь хотели сверхсекретного оператора рукопожатия для какой-то уникальной операции в вашем коде? Как играть в код-гольф? Попробуйте операторы, такие как - ~ + ~ - или <--- Последний из них используется в примерах для изменения порядка элементов.

Я не имею ничего общего с проектом Superators Project, кроме того, что восхищаюсь им.

Капитан Хаммер
источник
19

Я опаздываю на вечеринку, но:

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

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

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

(Это работает, потому что Array # zip "архивирует" значения из двух массивов:

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

И Hash [] может взять именно такой массив. Я видел, как люди это делают:

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

Что дает тот же результат, но сплат и сплющение совершенно не нужны - возможно, их не было в прошлом?)

Джордан Бег
источник
3
Это было действительно недокументированным долгое время (см. Redmine.ruby-lang.org/issues/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 } } }

Это может быть чертовски удобно.

Trevoke
источник
1
Я бы обернул его в модуль, чтобы у меня было такое же чувство, как у родного хеша init:module InfHash; def self.new; Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}; end; end
asaaki
16

Уничтожение массива

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

Куда:

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

Используя эту технику, мы можем использовать простое присваивание, чтобы получить нужные значения из вложенного массива любой глубины.

horseyguy
источник
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 создание нового метода, задачей которого является отправка сообщения, включая все аргументы и блоки.

Большой ресурс для вопросов метапрограммирования - « Почему Лаки Стифф« Видит метапрограммирование ясно » .

TALlama
источник
Я хочу сначала погрузиться в метапрограммирование в ruby. Не могли бы вы предоставить некоторые ссылки для начала работы (кроме указанной ссылки)? Книги тоже подойдут. Спасибо.
Chirantan
Videocasting серия PragProg в «The Ruby Object Model и Метапрограммирование» его хорошее введение в мета - программирование с использованием рубина: pragprog.com/screencasts/v-dtrubyom/...
caffo
@Chirantan, взгляни на Метапрограммирование 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

«Рубиновый» бинарный файл (по крайней мере, MRI) поддерживает множество переключателей, которые сделали Perl One-Liner довольно популярным.

Значительные из них:

  • -n Устанавливает внешний цикл с помощью «get», который волшебным образом работает с данным именем файла или STDIN, устанавливая каждую строку чтения в $ _
  • -p Аналогично -n, но с автоматическим puts в конце каждой итерации цикла
  • -a Автоматический вызов .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

Не стесняйтесь гуглить "ruby one-liners" и "perl one-liners" для множества более полезных и практических примеров. По сути, это позволяет вам использовать ruby ​​как довольно мощную замену awk и sed.

minaguib
источник
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: Приложение Simple-Calc

оборота CodingWithoutComments
источник
Звучит как отличный способ открыть дыру в безопасности.
мП
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")
olegueret
источник
Устраняет ли это проблемы, когда gem A требует foo-1.0.0, а gem B требует foo-1.0.1?
Эндрю Гримм
Нет, потому что код «что-то» не будет доступен: это только имитирует, что «что-то» требуется, но на самом деле это не требуется. $ "- это массив, содержащий имена модулей, загруженных с помощью require (он используется by require, чтобы предотвратить загрузку модулей дважды). Поэтому, если вы используете это, чтобы обмануть драгоценные камни, это вызовет сбой, когда драгоценные камни попытаются использовать фактическое" что-то " код, потому что он не существует. Вместо этого вы можете захотеть принудительно загрузить конкретную версию гема (например, foo-1.0.0) вместо последней: docs.rubygems.org/read/chapter/4#page71
olegueret
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"
sickill
источник
9

Определение метода, который принимает любое количество параметров и просто отбрасывает их все

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

Вышеупомянутый helloметод должен только puts "hello"отображаться на экране и вызываться super- но поскольку суперкласс helloопределяет параметры, он также должен это делать - однако поскольку ему фактически не нужно использовать сами параметры - ему не нужно давать им имя.

horseyguy
источник