The <<- Operator on Ruby, Where Is It Documented

The - operator on Ruby, where is it documented?

From The Ruby Programming Language:

Here Documents


For long string literals, there may be no single character delimiter that can be used without worrying about remembering to escape characters within the literal. Ruby's solution to this problem is to allow you to specify an arbitrary sequence of characters to serve as the delimiter for the string. This kind of literal is borrowed from Unix shell syntax and is historically known as a here document. (Because the document is right here in the source code rather than in an external file.)

Here documents begin with << or <<-. These are followed immediately (no space is allowed, to prevent ambiguity with the left-shift operator) by an identifier or string that specifies the ending delimiter. The text of the string literal begins on the next line and continues until the text of the delimiter appears on a line by itself. For example:

document = <<HERE        # This is how we begin a here document
This is a string literal.
It has two lines and abruptly ends...
HERE

The Ruby interpreter gets the contents of a string literal by reading a line at a time from its input. This does not mean, however, that the << must be the last thing on its own line. In fact, after reading the content of a here document, the Ruby interpreter goes back to the line it was on and continues parsing it. The following Ruby code, for example, creates a string by concatenating two here documents and a regular single-quoted string:

greeting = <<HERE + <<THERE + "World"
Hello
HERE
There
THERE

The <<HERE on line 1 causes the interpreter to read lines 2 and 3. And the <<THERE causes the interpreter to read lines 4 and 5. After these lines have been read, the three string literals are concatenated into one.

The ending delimiter of a here document really must appear on a line by itself: no comment may follow the delimiter. If the here document begins with <<, then the delimiter must start at the beginning of the line. If the literal begins with <<- instead, then the delimiter may have whitespace in front of it. The newline at the beginning of a here document is not part of the literal, but the newline at the end of the document is. Therefore, every here document ends with a line terminator, except for an empty here document, which is the same as "":

empty = <<END
END

If you use an unquoted identifier as the terminator, as in the previous examples, then the here document behaves like a double-quoted string for the purposes of interpreting backslash escapes and the # character. If you want to be very, very literal, allowing no escape characters whatsoever, place the delimiter in single quotes. Doing this also allows you to use spaces in your delimiter:

document = <<'THIS IS THE END, MY ONLY FRIEND, THE END'
.
. lots and lots of text goes here
. with no escaping at all.
.
THIS IS THE END, MY ONLY FRIEND, THE END

The single quotes around the delimiter hint that this string literal is like a single-quoted string. In fact, this kind of here document is even stricter. Because the single quote is not a delimiter, there is never a need to escape a single quote with a backslash. And because the backslash is never needed as an escape character, there is never a need to escape the backslash itself. In this kind of here document, therefore, backslashes are simply part of the string literal.

You may also use a double-quoted string literal as the delimiter for a here document. This is the same as using a single identifier, except that it allows spaces within the delimiter:

document = <<-"# # #"    # This is the only place we can put a comment
<html><head><title>#{title}</title></head>
<body>
<h1>#{title}</h1>
#{body}
</body>
</html>
# # #

Note that there is no way to include a comment within a here document except on the first line after the << token and before the start of the literal. Of all the # characters in this code, one introduces a comment, three interpolate expressions into the literal, and the rest are the delimiter

What does &. (ampersand dot) mean in Ruby?

It is called the Safe Navigation Operator. Introduced in Ruby 2.3.0, it lets you call methods on objects without worrying that the object may be nil(Avoiding an undefined method for nil:NilClass error), similar to the try method in Rails.

So you can write

@person&.spouse&.name

instead of

@person.spouse.name if @person && @person.spouse

From the Docs:

my_object.my_method

This sends the my_method message to my_object. Any
object can be a receiver but depending on the method's visibility
sending a message may raise a NoMethodError.

You may use &. to designate a receiver, then my_method is not invoked
and the result is nil when the receiver is nil. In that case, the
arguments of my_method are not evaluated.

What is the = operator on Ruby Classes?

See http://ruby-doc.org/core/classes/Module.html#M001669 for documentation on all the comparison operators exposed by Modules (and therefore Classes).

In this specific case:
"Returns true if mod is a subclass of other or is the same as other. Returns nil if there‘s no relationship between the two. (Think of the relationship in terms of the class definition: "class A < B" implies "A < B")."

What is stand for in ruby with integer

As the documentation says, Integer:<< - Returns the integer shifted left "X" positions, or right if "X" is negative. In your scenario is shifts 8 positions to the left.

Here is how it works:

8.to(2) => "1000"

Now let's shift "1000" 8 positions to the left

(8 << 8).to_s(2) => "100000000000"

If you count the 0 above you will see it added 8 after "1000".

Now, let's see how it returns 2048

"100000000000".to_i(2) => 2048

what's in ruby on rails model

Don't get it wrong. In the case of OP's question, << is not a method of Array. Instead, it's a method of ActiveRecord::Associations::CollectionProxy.

Source code here

  def <<(*records)
proxy_association.concat(records) && self
end
alias_method :push, :<<
alias_method :append, :<<

https://github.com/rails/rails/blob/b15ce4a006756a0b6cacfb9593d88c9a7dfd8eb0/activerecord/lib/active_record/associations/collection_proxy.rb#L944 (Code is for Rails 4, and in Rails 3 it works the same)

This method is for object which has_many other objects. The collection of other objects can use this method to add new associated object, association id assigned automatically and the new object got saved to db

class Question < ActiveRecord::Base
has_many :answers

question = Question.last # id: 100
question.answers.size # 0
question.answers << Answer.new(body: 'demo answer')

question.answers.size # 1

Answer.last # id: 1, question_id: 100, body: 'demo answer'
# Note here, the contacted answer got saved in db.

You can also use the aliased methods which works the same:

question.answers.push Answer.new(body: 'demo answer')
question.answers.append Answer.new(body: 'demo answer')

What does ||= (or-equals) mean in Ruby?

This question has been discussed so often on the Ruby mailing-lists and Ruby blogs that there are now even threads on the Ruby mailing-list whose only purpose is to collect links to all the other threads on the Ruby mailing-list that discuss this issue.

Here's one: The definitive list of ||= (OR Equal) threads and pages

If you really want to know what is going on, take a look at Section 11.4.2.3 "Abbreviated assignments" of the Ruby Language Draft Specification.

As a first approximation,

a ||= b

is equivalent to

a || a = b

and not equivalent to

a = a || b

However, that is only a first approximation, especially if a is undefined. The semantics also differ depending on whether it is a simple variable assignment, a method assignment or an indexing assignment:

a    ||= b
a.c ||= b
a[c] ||= b

are all treated differently.

Difference between or and || in Ruby?

It's a matter of operator precedence.

|| has a higher precedence than or.

So, in between the two you have other operators including ternary (? :) and assignment (=) so which one you choose can affect the outcome of statements.

Here's a ruby operator precedence table.

See this question for another example using and/&&.

Also, be aware of some nasty things that could happen:

a = false || true  #=> true
a #=> true

a = false or true #=> true
a #=> false

Both of the previous two statements evaluate to true, but the second sets a to false since = precedence is lower than || but higher than or.

rails - left shift operator saves record automatically

Maybe looking at the source code will help you. This is my trail of searches based on the << method in activerecord:

def <<(*records)
proxy_association.concat(records) && self
end

rails/collection_proxy.rb at 5053d5251fb8c03e666f1f8b765464ec33e3066e · rails/rails · GitHub

def concat(*records)
records = records.flatten
if owner.new_record?
load_target
concat_records(records)
else
transaction { concat_records(records) }
end
end

rails/collection_association.rb at 5053d5251fb8c03e666f1f8b765464ec33e3066e · rails/rails · GitHub

def concat_records(records, should_raise = false)
result = true

records.each do |record|
raise_on_type_mismatch!(record)
add_to_target(record) do |rec|
result &&= insert_record(rec, true, should_raise) unless owner.new_record?
end
end

result && records
end

rails/collection_association.rb at 5053d5251fb8c03e666f1f8b765464ec33e3066e · rails/rails · GitHub

  def insert_record(record, validate = true, raise = false)
set_owner_attributes(record)
set_inverse_instance(record)

if raise
record.save!(validate: validate)
else
record.save(validate: validate)
end
end

https://github.com/rails/rails/blob/5053d5251fb8c03e666f1f8b765464ec33e3066e/activerecord/lib/active_record/associations/has_many_association.rb#L32

  def insert_record(record, validate = true, raise = false)
ensure_not_nested

if record.new_record? || record.has_changes_to_save?
if raise
record.save!(validate: validate)
else
return unless record.save(validate: validate)
end
end

save_through_record(record)

record
end

https://github.com/rails/rails/blob/5053d5251fb8c03e666f1f8b765464ec33e3066e/activerecord/lib/active_record/associations/has_many_through_association.rb#L38

As you can see, in the end, it does call the save method.

Disclaimer: I'm not that familiar with Rails souce code, but you have interesting question.

Ruby unary tilde (`~`) method

Using pry to inspect the method:

show-method 1.~

From: numeric.c (C Method):
Owner: Fixnum
Visibility: public
Number of lines: 5

static VALUE
fix_rev(VALUE num)
{
return ~num | FIXNUM_FLAG;
}

While this is impenetrable to me, it prompted me to look for a C unary ~ operator. One exists: it's the bitwise NOT operator, which flips the bits of a binary integer (~1010 => 0101). For some reason this translates to one less than the negation of a decimal integer in Ruby.

More importantly, since ruby is an object oriented language, the proper way to encode the behavior of ~0b1010 is to define a method (let's call it ~) that performs bitwise negation on a binary integer object. To realize this, the ruby parser (this is all conjecture here) has to interpret ~obj for any object as obj.~, so you get a unary operator for all objects.

This is just a hunch, anyone with a more authoritative or elucidating answer, please enlighten me!

--EDIT--

As @7stud points out, the Regexp class makes use of it as well, essentially matching the regex against $_, the last string received by gets in the current scope.

As @Daiku points out, the bitwise negation of Fixnums is also documented.

I think my parser explanation solves the bigger question of why ruby allows ~ as global unary operator that calls Object#~.

Can I override the behavior of the assignment operator?

I'm assuming your are using attr_reader on @position to define the position method of the sprite. But you can also define your own getters. In this case I'd suggest you to create an explicit getter for the position:

class Sprite
def position
return Point.new(@position.x, @position.y)
end
end

It's very rare that you want to have a reference to the position of the sprite inside the object rather than a copy of its value; and it's actually quite dangerous to expose private members of a class.



Related Topics



Leave a reply



Submit