什么<<在Ruby中意味着什么

时间:2011-07-27 22:37:15

标签: ruby arrays operators

我有代码:

  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

<<是什么意思?

8 个答案:

答案 0 :(得分:100)

<强> '&LT;&LT;'作为一种普通的方法

在大多数情况下'&lt;&lt;&lt;是一个像其他方法一样定义的方法,在您的情况下,它意味着“添加到此数组的末尾”(另请参阅here)。

这是在你的特殊情况下,但也有很多其他场合会遇到“&lt;&lt;”方法。我不会将其称为'运算符',因为它实际上是一个在某个对象上定义的方法,可以被您覆盖或为您自己的对象实现。其他'&lt;&lt;&lt;'

的情况
  • 字符串连接:“a”&lt;&lt; “b” 的
  • 将输出写入IO:io&lt;&lt; “一行文字\ n”
  • 将数据写入消息摘要,HMAC或密码:sha&lt;&lt; “要散播的文字”
  • OpenSSL :: BN的左移:bn&lt;&lt; 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是'&lt;&lt;&lt; token,k_class是'class'关键字,expr是任意表达式。也就是说,你实际上可以写

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; 

此处文件

而且,我怎么能忘记那些, Here Documents 使用'&lt;&lt;'以一种完全不同的方式。您可以通过声明

来方便地定义跨越多行的字符串
here_doc = <<_EOS_
The quick brown fox jumps over the lazy dog.
...
_EOS_

要区分'here doc operator',任意String定界符必须紧跟'&lt;&lt;'。初始分隔符和第二次出现的相同分隔符之间的所有内容都将成为最终字符串的一部分。也可以使用'&lt;&lt; - &lt; - ',不同之处在于使用后者将忽略任何前导或尾随空格。

答案 1 :(得分:26)

主要用在数组中,将值附加到数组的末尾。

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

给出了

  ["orange", "apple"] 
结果。

答案 2 :(得分:7)

这是允许您通过附加新项目提供现有数组的运算符。

在上面的示例中,您只需使用5个新线程填充空数组threads

答案 3 :(得分:6)

'a&lt;&lt; b'表示将b附加到

的末尾

答案 4 :(得分:4)

在红宝石中,你总是有更多的办法。因此,Ruby有一些很好的常用方法名称快捷方式。像这样的.push而不是键入.push方法名称,你可以简单地使用&lt;&lt;,连接运算符。实际上在某些情况下,您可以使用其中任何一个进行相同的操作.push和+ with&lt;&lt;。

就像你在这个例子中看到的那样:

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.

你可以使用运算符&lt;&lt;将元素推入数组或将字符串连接到另一个。

所以,这样做是创建一个新的元素/对象线程类型并将其推入数组。

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

答案 5 :(得分:4)

在ruby&#39;&lt;&lt;&lt;&# operator基本上用于:

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

    [2,4,6]&lt;&lt; 8 它将给出[2,4,6,8]

  2. 它还用于ruby中的一些活动记录操作。例如,我们将Cart和LineItem模型关联为cart has_many line_items。 Cart.find(A).line_items将返回ActiveRecord :: Associations对象与属于购物车&#39; A&#39;。

  3. 的订单项。

    现在,要将另一个line_item(X)添加(或说关联)到购物车(A),

    Cart.find(A).line_items << LineItem.find(X)
    
    1. 现在将另一个LineItem添加到同一个购物车&#39; A&#39;,但这次我们不打算创建任何line_item对象(我的意思是不会手动创建activerecord对象)

      Cart.find(A).line_items&lt;&lt; LineItem.new

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

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

答案 6 :(得分:0)

表示添加到末尾(追加)。

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

答案 7 :(得分:0)

此外,自Ruby 2.6起,<<方法也在Proc上定义。

Proc#<<允许编写两个或多个proc。

相关问题