它可以有三种不同的含义:
'<<' as an ordinary method
在大多数情况下,<<;'是一个与其他方法一样定义的方法,在您的例子中,它意味着"添加到此数组的末尾"(另请参见here).
这是在你的特殊情况下,但也有很多其他情况下,你会遇到"<;<方法我不会称它为"操作符",因为它实际上是一个在某个对象上定义的方法,可以被您覆盖,也可以为您自己的对象实现.其他‘<<;'
- 字符串串联:"a"<&书信telegram ;"b"
- 将输出写入IO:IO<&书信telegram ;"一行文本\n"
- 将数据写入消息摘要、HMAC或密码:sha<&书信telegram ;"要散列的文本"
- OpenSSL的左移::BN:BN<&书信telegram ;2.
- ...
Singleton class definition
然后,在程序流中,当前范围(=自身的变化)发生了神秘的变化:
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
号让我对那里的内部 struct 感到好奇和调查.而在我提到的所有例子中,<<
实际上是一个在类中定义的方法,即.
obj << stuff
相当于
obj.<<(stuff)
class << self
(或任何代替self 的物体) struct 是完全不同的.它实际上是语言本身的一个内置功能,在克鲁比,它在parse.y年被定义为
k_class tLSHFT expr
k_class
是'class'关键字,其中tLSHFT
是'<;'token和expr
是任意表达式.也就是说,你实际上可以写作
class << <any expression>
并将shifted带入表达式结果的单例类.tLSHFT
序列将被解析为"NODE_SCLASS"表达式,称为Singleton Class definition(参见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 Documents
Here Documents使用"<<;'以一种完全不同的方式.可以通过声明
here_doc = <<_EOS_
The quick brown fox jumps over the lazy dog.
...
_EOS_
要区分"here doc operator",必须在"<<;'.初始定界符和同一定界符第二次出现之间的所有内容都将成为最终字符串的一部分.也可以使用"<<;-',不同之处在于,使用后者将忽略任何前导或尾随空格.