Подтвердить что ты не робот

Что означает << в Ruby?

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

  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

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

4b9b3361

Ответ 1

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

В большинстве случаев '< < это метод, определенный как остальные, в вашем случае это означает "добавить к концу этого массива" (см. также здесь).

Это в вашем конкретном случае, но есть также много других случаев, когда вы столкнетесь с "< lt; метод. Я не буду называть это" оператором", поскольку это действительно метод, который определен на каком-либо объекте, который может быть переопределен вами или реализован для ваших собственных объектов. Другие случаи '< lt;

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

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

Тогда в потоке программы есть таинственный сдвиг текущего объема (= изменение self):

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

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

Тайна class << self заставила меня задуматься и исследовать там внутренности. Если во всех примерах, упомянутых выше, << - это действительно метод, определенный в классе, т.е.

obj << stuff

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

obj.<<(stuff)

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

k_class tLSHFT expr

где tLSHFT представляет собой '< token, k_class - это ключевое слово 'class', а expr - произвольное выражение. То есть вы можете написать

class << <any expression>

и будет "смещаться" в одноэлементный класс результата выражения. Последовательность tLSHFT будет анализироваться как выражение 'NODE_SCLASS', которое называется определением класса Singleton (cf. 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; 

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

И как я мог забыть те, здесь Документы используют '< < таким образом, который снова совершенно другой. Вы можете легко определить строку, которая охватывает несколько строк, объявив

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

Чтобы отличить оператор "here doc", произвольный ограничитель строк должен немедленно следовать за "< lt;". Все, что находится между этим начальным разделителем и вторым вхождением этого же разделителя, будет частью окончательной строки. Также возможно использовать '< < -', разница заключается в том, что использование последнего будет игнорировать любые ведущие или конечные пробелы.

Ответ 2

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

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

дает результат

  ["orange", "apple"] 
.

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

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

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.

вы можете использовать оператор < < нажимать элемент в массив или конкатенировать строку в другую.

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

 threads << Thread.new(s) {
        create_thumbnail(source+'.png', source+'-'+s+'.png', s)
      }