What does << mean in Ruby?

前端 未结 8 627
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-04 12:13

I have code:

  def make_all_thumbs(source)
    sizes = [\'1000\',\'1100\',\'1200\',\'800\',\'600\']
    threads = []
    sizes.each do |s|
      threads <         


        
相关标签:
8条回答
  • 2020-12-04 12:17

    It's the operator which allows you to feed existing arrays, by appending new items.

    In the example above you are just populating the empty array threads with 5 new threads.

    0 讨论(0)
  • 2020-12-04 12:18

    In ruby '<<' operator is basically used for:

    1. Appending a value in the array (at last position)

      [2, 4, 6] << 8 It will give [2, 4, 6, 8]

    2. It also used for some active record operations in ruby. For example we have a Cart and LineItem model associated as cart has_many line_items. Cart.find(A).line_items will return ActiveRecord::Associations object with line items that belongs to cart 'A'.

    Now, to add (or say to associate) another line_item (X) to cart (A),

    Cart.find(A).line_items << LineItem.find(X)
    
    1. Now to add another LineItem to the same cart 'A', but this time we will not going to create any line_item object (I mean will not create activerecord object manually)

      Cart.find(A).line_items << LineItem.new

    In above code << will save object and append it to left side active record association array.

    And many others which are already covered in above answers.

    0 讨论(0)
  • 2020-12-04 12:22

    'a << b' means append b to the end of a

    0 讨论(0)
  • 2020-12-04 12:28

    '<<' 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
    

    where tLSHFT is a '<<' token, k_class is the 'class' keyword 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

    And, how could I forget those, 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.

    0 讨论(0)
  • 2020-12-04 12:30

    It means add to the end (append).

    a = [1,2,3]
    a << 4
    a = [1,2,3,4]
    
    0 讨论(0)
  • 2020-12-04 12:32

    In ruby you always have more the one way to do things. So, Ruby has some nice shortcuts for common method names. like this one is for .push instead of typing out the .push method name, you can simply use <<, the concatenation operator. in fact in some cases you can use any of these for the same operation .push and + with <<.

    Like you can see in this example:

    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
    

    so you see the result is:

    ["a", "b", "c", "d", "e"]
    the boy is surrounded by weezards! and more.
    

    you can use the operator << to push a element into an array or to concatenate a string to another.

    so, what this is this doing is creating a new element/object Thread type and pushing it into the array.

     threads << Thread.new(s) {
            create_thumbnail(source+'.png', source+'-'+s+'.png', s)
          }
    
    0 讨论(0)
提交回复
热议问题