||=<<'<<' as an ordinary methodAppend to the end of the array (most common)Concatenate two strings (most common)Writing output to an IOWriting data to a message digest, HMAC or cipher?*:!In front of a variableAfter a methodPart of a method nameConvention to indicate "in-place" modificationsSometimes ! means mutation on the objectIn Rails as a convention, method! raise an exceptionSources
||=
a ||= b
If a is
nil
or false
, then a = b.irb(main):001:0> x = true
=> true
irb(main):002:0> x ||= "ruby"
=> true
irb(main):003:0> x
=> true
# And, likewise, with nil:
irb(main):014:0> x = nil
=> nil
irb(main):015:0> x ||= "ruby"
=> "ruby"
irb(main):016:0> x
=> "ruby"
# Also with false
irb(main):019:0> x = false
=> false
irb(main):020:0> x ||= "ruby"
=> "ruby"
irb(main):021:0> x
=> "ruby"
<<
'<<' as an ordinary method
Append to the end of the array (most common)
array = []
array << new_element
Concatenate two strings (most common)
"a" << "b"
Writing output to an IO
io << "new line\n"
Writing data to a message digest, HMAC or cipher
sha << "Text to be hashed"
?
It is a code style convention; it indicates that a method returns a boolean value (true or false) or an object to indicate a true value (or “truthy” value).
if alvin.present?
puts "alvin is present"
end
*
Like a pointer?
No! It is just like unwrap a list of arguments in Python.
:
- A colon before text indicates a symbol in Ruby
!
In front of a variable
Just like
not
, but !
has a higher precedence.!true && false
=> false
not true && false
=> true # (true && false) is false
After a method
Part of a method name
Surprise!
!
or ?
are allowed in method names.Convention to indicate "in-place" modifications
String#gsub
: return a copyString#gsub!
: modify string in-placeSometimes ! means mutation on the object
my_string.downcase() # returns a new instance
my_string.downcase!() # override the object
In Rails as a convention, method!
raise an exception
Record.find_by(id: 10) # => Can return nil if not found
Record.find_by!(id: 10) # => Can raise ActiveRecord::RecordNotFound
This makes flow-control easier and code cleaner.
# update without !
def update
if (user.save)
if (purchase.save)
if (email.sent?)
redirect_to(success_path)
else
render(template: 'invalid_email')
end
else
render(template: 'edit')
end
else
render(template: 'edit')
end
end
# update using !
def update
user.save!
purchase.save!
email.send!
redirect_to(success_path)
rescue ActiveRecord::RecordNotFound
render(template: 'edit')
rescue SomeMailer::EmailNotSent
render(template: 'invalid_email')
end