I have code:

  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

what does << mean?

推荐答案

It can have 3 distinct meanings:

'<<' as an ordinary method

In most cases '<<' is a method defined like the rest of them, in your case it means "add to the end of this array" (see also here).

That's in your particular case, but there are also a lot of other occasions where you'll encounter the "<<" method. I won't call it 'operator' since it's really a method that is defined on some object that can be overridden by you or implemented for your own objects. Other cases of '<<'

  • String concatenation: "a" << "b"
  • Writing output to an IO: io << "A line of text\n"
  • Writing data to a message digest, HMAC or cipher: sha << "Text to be hashed"
  • left-shifting of an OpenSSL::BN: bn << 2
  • ...

Singleton class definition

Then there is the mysterious shift of the current scope (=change of self) within the program flow:

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

The mystery class << self made me wonder and investigate about the internals there. Whereas in all the examples I mentioned << is really a method defined in a class, i.e.

obj << stuff

is equivalent to

obj.<<(stuff)

the class << self (or any object in place of self) construct is truly different. It is really a builtin feature of the language itself, in CRuby it's defined in parse.y as

k_class tLSHFT expr

k_class is the 'class' keyword, where tLSHFT is a '<<' token and expr is an arbitrary expression. That is, you can actually write

class << <any expression>

and will get shifted into the singleton class of the result of the expression. The tLSHFT sequence will be parsed as a 'NODE_SCLASS' expression, which is called a Singleton Class definition (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 Documents

Here Documents use '<<' in a way that is again totally different. You can define a string that spans over multiple lines conveniently by declaring

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

To distinguish the 'here doc operator' an arbitrary String delimiter has to immediately follow the '<<'. Everything inbetween that initial delimiter and the second occurrence of that same delimiter will be part of the final string. It is also possible to use '<<-', the difference is that using the latter will ignore any leading or trailing whitespace.

Ruby相关问答推荐

Ruby 中使用的-S标志是什么?

在Ruby中将嵌套哈希键从CamelCase转换为snake_case

什么是 '?-mix' 在 Ruby 正则表达式中

用于 ruby​​ gems 的新 10.9 OSX 的命令行工具?

哈希或其他对象的内存大小?

在 gem 中放置/访问配置文件的位置?

如果浮点组件不是 .00 sprintf/printf,则仅显示小数点

确保如何在 ruby​​ 中工作

全新安装 RVM 和 Ruby 2.1.1 - dyld 库/路径错误

GET 和 POST 请求的相同 Rails 4 路由

在文件中搜索字符串的最佳方法是什么?

Ruby 的排序方法使用哪种算法?

将haml标签放入link_to helper

无法正确自动生成 Ruby DevKit 配置文件

如何在 ruby​​ rake 中明确地失败任务?

如何在Ruby中对数组中对象的属性求和

用 Ruby 解析 XML

Ruby 中的标准文件命名约定

如何让 Ruby 1.9 成为 Ubuntu 上的默认 Ruby?

`File` 对象访问模式的区别(即 w+, r+)