'<<' как обычный метод </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>