Что означает << в Ruby? - PullRequest
56 голосов
/ 28 июля 2011

У меня есть код:

  def make_all_thumbs(source)
    sizes = ['1000','1100','1200','800','600']
    threads = []
    sizes.each do |s|
      threads << Thread.new(s) {
        create_thumbnail(source+'.png', source+'-'+s+'.png', s)
      }
    end
  end

что означает <<?

Ответы [ 6 ]

102 голосов
/ 28 июля 2011

'<<' как обычный метод </strong>

В большинстве случаев «<<» - это метод, определенный как остальные, в вашем случае это означает «добавить в конец»этого массива "(см. также <a href="http://www.ruby-doc.org/core/classes/Array.html#M000225" rel="noreferrer"> здесь ).

Это в вашем конкретном случае, но есть также много других случаев, когда вы сталкиваетесь с методом «<<».Я не буду называть это «оператором», поскольку это действительно метод, который определен для некоторого объекта, который может быть переопределен вами или реализован для ваших собственных объектов.Другие случаи '<<' </p>

  • Конкатенация строк: "a" << "b" </li>
  • Запись вывода в IO: io << "Строка текста \ n"</li>
  • Запись данных в дайджест сообщения, HMAC или шифр: sha << «Текст для хэширования» </li>
  • смещение влево OpenSSL :: BN: bn << 2 </li>
  • ...

Определение класса Singleton

Затем происходит таинственный сдвиг текущей области видимости (= изменение себя) в пределахход программы:

class A
  class << self
    puts self # self is the singleton class of A
  end
end

a = A.new
class << a
  puts self # now it's the singleton class of object a
end

Загадка class << self заставила меня задуматься и выяснить, что там происходит.В то время как во всех упомянутых мною примерах << действительно является методом, определенным в классе, то есть

obj << stuff

эквивалентно

obj.<<(stuff)

class << self (или любому объекту вместо самости) конструкции действительно отличается.Это действительно встроенная функция самого языка, в CRuby он определен в parse.y как

k_class tLSHFT expr

, где tLSHFT - токен «<<», k_class - «класс»Ключевое слово и expr - произвольное выражение.То есть вы можете написать </p>

class << <any expression>

и получить «смещение» в класс синглтона результата выражения.Последовательность tLSHFT будет проанализирована как выражение 'NODE_SCLASS', которое называется определением класса Singleton (ср. Node.c)

case NODE_SCLASS:
    ANN("singleton class definition");
    ANN("format: class << [nd_recv]; [nd_body]; end");
    ANN("example: class << obj; ..; end");
    F_NODE(nd_recv, "receiver");
    LAST_NODE;
    F_NODE(nd_body, "singleton class definition");
    break; 

Здесь документы

И, как я мог забыть об этом, Здесь Документы используют «<<» таким образом, что снова совершенно другой.Вы можете легко определить строку, которая охватывает несколько строк, объявив </p>

here_doc = <<_EOS_
The quick brown fox jumps over the lazy dog.
...
_EOS_

Чтобы отличить «оператор here doc», произвольный разделитель строк должен следовать сразу за «<<».Все, что находится между этим начальным разделителем и вторым вхождением того же самого разделителя, будет частью окончательной строки.Также можно использовать «<< -», разница в том, что при использовании последнего игнорируются любые начальные или конечные пробелы. </p>

26 голосов
/ 28 июля 2011

Чаще всего используется в массивах для добавления значения в конец массива.

a = ["orange"]
a << "apple"
puts a

дает этот

["orange", "apple"] 
результат.
7 голосов
/ 28 июля 2011

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

В приведенном выше примере вы просто заполняете пустой массив threads 5 новыми потоками.

6 голосов
/ 28 июля 2011

'a << b' означает добавление b к концу a </p>

4 голосов
/ 09 марта 2018

В ruby ​​оператор «<<» в основном используется для: </p>

  1. Добавление значения в массиве (в последней позиции)

    [2, 4, 6] << 8 Это даст [2, 4, 6, 8] </p>

  2. Он также используется для некоторых активных операций записи в ruby. Например, у нас есть модель Cart и LineItem, связанная как корзина has_many line_items. Cart.find (A) .line_items вернет объект ActiveRecord :: Associations с позициями, которые принадлежат корзине «A».

Теперь, чтобы добавить (или, скажем, связать) еще один line_item (X) в корзину (A),

Cart.find(A).line_items << LineItem.find(X)
  1. Теперь добавим еще один LineItem в ту же корзину 'A', но на этот раз мы не собираемся создавать объект line_item (я имею в виду, что не будем создавать объект activerecord вручную)

    Cart.find (A) .line_items << LineItem.new </p>

В приведенном выше коде << сохранит объект и добавит его в массив ассоциаций активной записи слева. </p>

И многие другие, которые уже описаны в ответах выше.

4 голосов
/ 08 марта 2015

В ruby ​​у вас всегда есть один единственный способ сделать что-то. Итак, в Ruby есть несколько хороших ярлыков для общих имен методов. как этот для .push вместо того, чтобы вводить имя метода .push, вы можете просто использовать <<, оператор конкатенации. фактически в некоторых случаях вы можете использовать любой из них для одной и той же операции .push и + с <<. </p>

Как вы можете видеть в этом примере:

alphabet = ["a", "b", "c"]
alphabet << "d" # Update me!
alphabet.push("e") # Update me!
print alphabet 
caption = "the boy is surrounded by "
caption << "weezards!" # Me, too!
caption += " and more. " # Me, too!
# .push can no be uses for concatenate 
print caption

так что вы видите результат:

["a", "b", "c", "d", "e"]
the boy is surrounded by weezards! and more.

вы можете использовать оператор <<, чтобы вставить элемент в массив или объединить строку с другим. </p>

Итак, что это делает, создает новый тип потока элемента / объекта и помещает его в массив.

 threads << Thread.new(s) {
        create_thumbnail(source+'.png', source+'-'+s+'.png', s)
      }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...