<<在Ruby中是什么意思?


79

我有代码:

  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

什么<<意思

Answers:


140

'<<'作为常规方法

在大多数情况下,'<<'是与其他方法一样定义的方法,在您的情况下,它的意思是“添加到此数组的末尾”(另请参见此处)。

这是在您的特定情况下,但在其他许多情况下,您也会遇到“ <<”方法。我不会称其为“运算符”,因为它实际上是在某些对象上定义的方法,可以被您覆盖或为您自己的对象实现。其他情况“ <<”

  • 字符串串联:“ a” <<“ b”
  • 将输出写入IO:io <<“一行文本\ n”
  • 将数据写入消息摘要,HMAC或密码:sha <<“要散列的文本”
  • OpenSSL :: BN的左移:bn << 2
  • ...

单例类定义

然后程序流中当前范围的神秘变化(=自身的变化):

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是'class'关键字,而expr是任意表达式。也就是说,你实际上可以写

class << <any expression>

并将“转移”到表达式结果的单例类中。tLSHFT序列将被解析为“ NODE_SCLASS”表达式,称为“单例类”定义(请参阅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 operator”,必须使用任意的字符串定界符紧跟在“ <<”之后。在该初始定界符和该定界符的第二次出现之间的所有内容都将成为最终字符串的一部分。也可以使用'<<-',不同之处在于使用后者将忽略任何前导或尾随空格。


4
非常彻底的答案。可能会使初学者感到困惑,但是正如一个明智的人(可能)说的那样,“问一个广泛的问题,得到一个彻底的答案”。
开尔文2012年

1
嗨,谢谢@emboss:所以<<等价于在数组上调用push方法?
BKSpurgeon '16

30

通常用于数组中,以将值附加到数组的末尾。

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

给这个

  [“橙色”,“苹果”] 
结果。


3
还有一个使用的<<类的继承
Zabba



6

在红宝石中,您总是有更多的做事方式。因此,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)
      }

5

在Ruby中,'<<'运算符主要用于:

  1. 在数组中附加一个值(在最后一个位置)

    [2,4,6] << 8将给出[2,4,6,8]

  2. 它还用于红宝石中的一些活动记录操作。例如,我们有一个Cart和LineItem模型关联为cart 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

在上面的代码中,<<将保存对象并将其附加到左侧活动记录关联数组。

以及以上答案中已经涵盖的许多其他内容。


并非所有人都知道<<的行为。感谢您提及。
Ammar Shah

0

这意味着添加到末尾(追加)。

a = [1,2,3]
a << 4
a = [1,2,3,4]

0

另外,从Ruby 2.6开始,该<<方法也在上定义Proc

Proc#<<允许组成两个或多个proc。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.