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 tomy_object
. Any
object can be a receiver but depending on the method's visibility
sending a message may raise aNoMethodError
.You may use
&.
to designate a receiver, thenmy_method
is not invoked
and the result isnil
when the receiver isnil
. In that case, the
arguments ofmy_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 Fixnum
s 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
Include Jekyll/Liquid Template Data in a Yaml Variable
Why Does Ruby'S 'Gets' Includes the Closing Newline
How to Make Sinatra Work Over Https/Ssl
How to Convert Json to a Ruby Hash
Really Cheap Command-Line Option Parsing in Ruby
Uniq by Object Attribute in Ruby
Passing a Method as a Parameter in Ruby
Extract Number from String in Ruby
How to Check If a Ruby Object Is a Boolean
Private Module Methods in Ruby
Correctly Doing Redirect_To :Back in Ruby on Rails When Referrer Is Not Available