Продолжая тему «Скрытые возможности ...», давайте расскажем о менее известных, но полезных функциях языка программирования Ruby.
Попытайтесь ограничить это обсуждение ядром Ruby, без каких-либо вещей Ruby on Rails.
Смотрите также:
- Скрытые возможности C #
- Скрытые возможности Java
- Скрытые возможности JavaScript
- Скрытые возможности Ruby on Rails
- Скрытые возможности Python
(Пожалуйста, только одна скрытая функция в ответ.)
Спасибо
ruby
hidden-features
эскадрон
источник
источник
Ответы:
Начиная с Ruby 1.9, Proc # === является псевдонимом вызова Proc #, что означает, что объекты Proc могут использоваться в выражениях case следующим образом:
источник
У Питера Купера есть хороший список рубиновых трюков. Возможно, мой фаворит - разрешить перечисление как отдельных предметов, так и коллекций. (То есть обрабатывайте объект, не являющийся коллекцией, как коллекцию, содержащую только этот объект.) Это выглядит так:
источник
items
это строка, вам не нужно заключать ее в [*…]. String.each не выполняет итерации по символам, как некоторые могут ожидать. Он просто возвращает себя в блок.Не знаю, насколько это скрыто, но я нашел это полезным, когда нужно сделать хеш из одномерного массива:
источник
Hash[ [["apple","red"], ["banana","yellow"] ]
дает тот же результат.Один трюк, который мне нравится, - это использовать
*
расширитель splat ( ) для объектов, отличных от массивов. Вот пример соответствия регулярному выражению:Другие примеры включают в себя:
источник
text, number = *"text 555".match(/regexp/)[1..-1]
.text, number = "Something 981".scan(/([A-z]*) ([0-9]*)/).flatten.map{|m| Integer(m) rescue m}
Вау, никто не упомянул оператор триггера:
источник
i == 3
и переключается на false послеi != 3
иi == 15
. Похоже на триггер: en.wikipedia.org/wiki/Flip-flop_%28electronics%29Одна из замечательных особенностей ruby заключается в том, что вы можете вызывать методы и выполнять код в тех местах, где другие языки будут недовольны, например, в определениях методов или классов.
Например, чтобы создать класс, который имеет неизвестный суперкласс до времени выполнения, т.е. является случайным, вы можете сделать следующее:
Здесь используется
Array#sample
метод 1.9 (только в 1.8.7, см.Array#choice
), И пример довольно надуманный, но здесь вы можете увидеть всю мощь.Еще один крутой пример - возможность выставлять значения параметров по умолчанию, которые не являются фиксированными (как часто требуют другие языки):
Конечно, проблема с первым примером состоит в том, что он оценивается во время определения, а не во время вызова. Таким образом, после выбора суперкласса он остается этим суперклассом до конца программы.
Однако, во втором примере, каждый раз при вызове
do_something_at
, тоat
переменная будет время , что метод был назван (ну, очень и очень близко к нему)источник
require 'activesupport'
Еще одна крошечная функция - конвертировать
Fixnum
в любую базу до 36:И, как прокомментировал Хью Уолтерс, преобразование в другую сторону так же просто:
источник
String#to_s(base)
может быть использован для преобразования обратно в целое число;"1001001100101100000001011010010".to_i(2)
и"499602d2".to_i(16)
т. д. все возвращают оригиналFixnum
.Хеши со значениями по умолчанию! Массив в этом случае.
Очень полезно в метапрограммировании.
источник
Загрузите исходный код Ruby 1.9 и выполните выдачу
make golf
, тогда вы можете делать такие вещи:Прочитайте
golf_prelude.c
для более аккуратных вещей, скрывающихся.источник
Еще одно забавное дополнение в функциональности 1.9 Proc - это Proc # curry, который позволяет превратить Proc, принимающий n аргументов, в один, принимающий n-1. Здесь он объединен с советом Proc # ===, о котором я упоминал выше:
источник
Булевы операторы на не булевых значениях.
&&
и||
Оба возвращают значение последнего оцененного выражения.
Вот почему
||=
переменная обновит значение с выражением, возвращаемым справа, если переменная не определена. Это явно не задокументировано, но общеизвестно.Однако об
&&=
этом не так широко известно.эквивалентно
Это очень удобно для деструктивных операций, которые не должны продолжаться, если переменная не определена.
источник
string &&= string + "suffix"
эквивалентноstring = string && string + "suffix"
. Это&&
и||
возвращение их второй аргумент обсуждается в PickAx, с. 154 (часть I - аспекты Ruby, выражения, условное выполнение).Функция Symbol # to_proc, которую предоставляет Rails, действительно классная.
Вместо того
Ты можешь написать:
источник
require 'activesupport'
потому что именно отсюда большинство этих помощников.И последнее: в ruby вы можете использовать любой символ, который хотите разделить. Возьмите следующий код:
Если вы не хотите избегать двойных кавычек в строке, вы можете просто использовать другой разделитель:
Помимо того, что вам не нужно избегать разделителей, вы можете использовать эти разделители для более хороших многострочных строк:
источник
Я считаю, что использование команды define_method для динамической генерации методов довольно интересно и не так хорошо известно. Например:
Приведенный выше код использует команду define_method для динамического создания методов «press1» - «press9». Вместо того, чтобы вводить все 10 методов, которые по сути содержат один и тот же код, команда define method используется для генерации этих методов на лету по мере необходимости.
источник
Используйте объект Range в качестве бесконечного ленивого списка:
Более подробная информация здесь: http://banisterfiend.wordpress.com/2009/10/02/wtf-infinite-ranges-in-ruby/
источник
module_function
Методы модуля, которые объявлены как module_function , создадут свои копии как частные методы экземпляра в классе, который включает в себя модуль:
Если вы используете module_function без каких-либо аргументов, то любые методы модуля, которые идут после оператора module_function, автоматически сами становятся module_functions.
источник
module_function
(2-й способ) - просто использоватьextend self
(что выглядит довольно неплохо: D)Коротко впрысните, вот так:
Сумма диапазона:
источник
require 'backports'
:-)Предупреждение: этот предмет был выбран # 1 Самый ужасный хак 2008 года , поэтому используйте его с осторожностью. На самом деле, избегайте этого, как чумы, но это, безусловно, скрытый рубин.
Суператоры добавляют новых операторов в Ruby
Вы когда-нибудь хотели сверхсекретного оператора рукопожатия для какой-то уникальной операции в вашем коде? Как играть в код-гольф? Попробуйте операторы, такие как - ~ + ~ - или <--- Последний из них используется в примерах для изменения порядка элементов.
Я не имею ничего общего с проектом Superators Project, кроме того, что восхищаюсь им.
источник
Я опаздываю на вечеринку, но:
Вы можете легко взять два массива одинаковой длины и превратить их в хеш, один из которых содержит ключи, а другой - значения:
(Это работает, потому что Array # zip "архивирует" значения из двух массивов:
И Hash [] может взять именно такой массив. Я видел, как люди это делают:
Что дает тот же результат, но сплат и сплющение совершенно не нужны - возможно, их не было в прошлом?)
источник
Авто-живительные хэши в Ruby
Это может быть чертовски удобно.
источник
module InfHash; def self.new; Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}; end; end
Уничтожение массива
Куда:
Используя эту технику, мы можем использовать простое присваивание, чтобы получить нужные значения из вложенного массива любой глубины.
источник
Class.new()
Создайте новый класс во время выполнения. Аргумент может быть производным классом, а блок является телом класса. Возможно, вы также захотите посмотреть, как
const_set/const_get/const_defined?
правильно зарегистрировать новый класс, чтобыinspect
печатать имя вместо числа.Не то, что вам нужно каждый день, но довольно удобно, когда вы делаете.
источник
MyClass = Class.new Array do; def hi; 'hi'; end; end
кажется эквивалентнымclass MyClass < Array; def hi; 'hi'; end; end
.создать массив последовательных чисел:
устанавливает х в [0, 1, 2, 3, 4, 5]
источник
*
) в основном вызывает вto_a
любом случае.Большая магия, которую вы видите в Rubyland, связана с метапрограммированием, которое заключается в простом написании кода, который пишет код для вас. Ruby's
attr_accessor
,attr_reader
иattr_writer
все это простое метапрограммирование, поскольку они создают два метода в одной строке, следуя стандартному шаблону. Rails делает много метапрограммирования со своими методами управления отношениями, такими какhas_one
иbelongs_to
.Но довольно просто создать свои собственные приемы метапрограммирования, используя
class_eval
для выполнения динамически написанного кода.В следующем примере объект-оболочка позволяет перенаправлять определенные методы во внутренний объект:
Метод
Wrapper.forwards
принимает символы для имен методов и сохраняет их вmethods
массиве. Затем для каждого из указанных мы используемdefine_method
создание нового метода, задачей которого является отправка сообщения, включая все аргументы и блоки.Большой ресурс для вопросов метапрограммирования - « Почему Лаки Стифф« Видит метапрограммирование ясно » .
источник
используйте все, что отвечает
===(obj)
для сравнения случаев:Module
(и, таким образомClass
)Regexp
,Date
, и многие другие классы определяют метод экземпляра: === (другой), и все они могут быть использованы.Спасибо Фаррелу за напоминание о
Proc#call
псевдониме, какProc#===
в Ruby 1.9.источник
«Рубиновый» бинарный файл (по крайней мере, MRI) поддерживает множество переключателей, которые сделали Perl One-Liner довольно популярным.
Значительные из них:
put
s в конце каждой итерации циклаНекоторые примеры:
Не стесняйтесь гуглить "ruby one-liners" и "perl one-liners" для множества более полезных и практических примеров. По сути, это позволяет вам использовать ruby как довольно мощную замену awk и sed.
источник
Метод send () - это метод общего назначения, который можно использовать с любым классом или объектом в Ruby. Если не переопределено, send () принимает строку и вызывает имя метода, для которого она передана. Например, если пользователь нажимает кнопку «Clr», строка «press_clear» будет отправлена методу send () и будет вызван метод «press_clear». Метод send () позволяет весело и динамично вызывать функции в Ruby.
Я больше говорю об этой функции в Blogging Shoes: Приложение Simple-Calc
источник
Обмани некоторый класс или модуль, говорящий, что он требует чего-то, что ему действительно не нужно:
Это полезно, например, когда требуется A, который, в свою очередь, требует B, но нам не нужен B в нашем коде (и A не будет использовать его в нашем коде):
Например, Backgroundrb
bdrb_test_helper requires
'test/spec'
, но вы не используете его вообще, так что в вашем коде:источник
Fixnum#to_s(base)
может быть действительно полезным в некоторых случаях. Одним из таких случаев является генерация случайных (псевдо) уникальных токенов путем преобразования случайного числа в строку, используя основание 36.Токен длины 8:
Жетон длины 6:
источник
Определение метода, который принимает любое количество параметров и просто отбрасывает их все
Вышеупомянутый
hello
метод должен толькоputs
"hello"
отображаться на экране и вызыватьсяsuper
- но поскольку суперклассhello
определяет параметры, он также должен это делать - однако поскольку ему фактически не нужно использовать сами параметры - ему не нужно давать им имя.источник