What does +@ mean as a method in ruby
Ruby contains a few unary operators, including +
, -
, !
, ~
, &
and *
. As with other operators you can also redefine these. For ~
and !
you can simply just say def ~
and def !
as they don't have a binary counterpart (e.g. you cannot say a!b
).
However for -
and +
there is both a unary, and a binary version (e.g. a+b
and +a
are both valid), so if you want to redefine the unary version you have to use def +@
and def -@
.
Also note that there is a unary version of *
and &
as well, but they have special meanings. For *
it is tied to splatting the array, and for &
it is tied to converting the object to a proc, so if you want to use them you have to redefine to_a
and to_proc
respectively.
Here is a more complete example showing all kinds of the unary operators:
class SmileyString < String
def +@
SmileyString.new(self + " :)")
end
def -@
SmileyString.new(self + " :(")
end
def ~
SmileyString.new(self + " :~")
end
def !
SmileyString.new(self + " :!")
end
def to_proc
Proc.new { |a| SmileyString.new(self + " " + a) }
end
def to_a
[SmileyString.new(":("), self]
end
end
a = SmileyString.new("Hello")
p +a # => "Hello :)"
p ~a # => "Hello :~"
p *a # => [":(", "Hello"]
p !a # => "Hello :!"
p +~a # => "Hello :~ :)"
p *+!-~a # => [":(", "Hello :~ :( :! :)"]
p %w{:) :(}.map &a # => ["Hello :)", "Hello :("]
In your example the Module just simply defines an unary + operator, with a default value of not doing anything with the object (which is a common behaviour for the unary plus, 5
and +5
usually mean the same thing). Mixing in with any class would mean the class immediately gets support for using the unary plus operator, which would do nothing much.
For example (using ruby <=2.2
):
module M
def +@
self
end
end
p +"Hello" # => NoMethodError: undefined method `+@' for "Hello":String
class String
include M
end
p +"Hello" # => "Hello"
Note that in this example you can clearly see from the error message that the +@
method is missing from the class
Note that the above example will be different from Ruby 2.3, as the unary minus and plus are defined for Strings since that version, and they refer to returning a frozen and unfrozen string from the original.
What does ! mean at the end of a Ruby method definition?
Ruby doesn't treat the !
as a special character at the end of a method name. By convention, methods ending in !
have some sort of side-effect or other issue that the method author is trying to draw attention to. Examples are methods that do in-place changes, or might throw an exception, or proceed with an action despite warnings.
For example, here's how String#upcase!
compares to String#upcase
:
1.9.3p392 :004 > foo = "whatever"
=> "whatever"
1.9.3p392 :005 > foo.upcase
=> "WHATEVER"
1.9.3p392 :006 > foo
=> "whatever"
1.9.3p392 :007 > foo.upcase!
=> "WHATEVER"
1.9.3p392 :008 > foo
=> "WHATEVER"
ActiveRecord makes extensive use of bang-methods for things like save!
, which raises an exception on failure (vs save
, which returns true/false but doesn't raise an exception).
It's a "heads up!" flag, but there's nothing that enforces this. You could end all your methods in !
, if you wanted to confuse and/or scare people.
What is the purpose of ! and ? at the end of method names?
It's "just sugarcoating" for readability, but they do have common meanings:
- Methods ending in
!
perform some permanent or potentially dangerous change; for example:Enumerable#sort
returns a sorted version of the object whileEnumerable#sort!
sorts it in place.- In Rails,
ActiveRecord::Base#save
returns false if saving failed, whileActiveRecord::Base#save!
raises an exception. Kernel::exit
causes a script to exit, whileKernel::exit!
does so immediately, bypassing any exit handlers.
- Methods ending in
?
return a boolean, which makes the code flow even more intuitively like a sentence —if number.zero?
reads like "if the number is zero", butif number.zero
just looks weird.
In your example, name.reverse
evaluates to a reversed string, but only after the name.reverse!
line does the name
variable actually contain the reversed name. name.is_binary_data?
looks like "is name
binary data?".
Why are exclamation marks used in Ruby methods?
In general, methods that end in !
indicate that the method will modify the object it's called on. Ruby calls these as "dangerous methods" because they change state that someone else might have a reference to. Here's a simple example for strings:
foo = "A STRING" # a string called foo
foo.downcase! # modifies foo itself
puts foo # prints modified foo
This will output:
a string
In the standard libraries, there are a lot of places you'll see pairs of similarly named methods, one with the !
and one without. The ones without are called "safe methods", and they return a copy of the original with changes applied to the copy, with the callee unchanged. Here's the same example without the !
:
foo = "A STRING" # a string called foo
bar = foo.downcase # doesn't modify foo; returns a modified string
puts foo # prints unchanged foo
puts bar # prints newly created bar
This outputs:
A STRING
a string
Keep in mind this is just a convention, but a lot of Ruby classes follow it. It also helps you keep track of what's getting modified in your code.
What does || between methods mean?
The ||
operator means the same regardless of how complex the expressions are on each side of it.
A || B
means:
- evaluate
A
- if
A == false
orA == nil
- evaluate
B
- return the value of
B
as the value of theA || B
expression
- evaluate
- otherwise return the value of
A
as the value of theA || B
expression
What does the question mark at the end of a method name mean in Ruby?
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).
The question mark is a valid character at the end of a method name.
https://docs.ruby-lang.org/en/2.0.0/syntax/methods_rdoc.html#label-Method+Names
what does ? ? mean in ruby
Functions that end with ? in Ruby are functions that only return a boolean, that is, true, or false.
When you write a function that can only return true or false, you should end the function name with a question mark.
The example you gave shows a ternary statement, which is a one-line if-statement. .nil?
is a boolean function that returns true if the value is nil and false if it is not. It first checks if the function is true, or false. Then performs an if/else to assign the value (if the .nil?
function returns true, it gets nil as value, else it gets the File.join(root_dir, '/')
as value.
It can be rewritten like so:
if root_dir.nil?
prefix = nil
else
prefix = File.join(root_dir, '/')
end
What does def (some param) mean in Ruby? How is it used in a class?
In your class definition for MyClass
:
Member
is a class equal to an instance of theStruct
class.mc = MyClass.new
initializes the instance variable@members
to an empty array.mc << "Bob"
is the same asmc.<<("Bob")
and causes the structMember.new("Bob")
to be appended to the array@members
. You are definingMyClass#<<
by using Array#<< within the method definition (since@members
is an array).
mc << "Bob"
is obtained from mc.<<("Bob")
by dropping the optional parentheses around <<
's argument ("Bob"
) and adding a teaspoon of "syntactic sugar", permitting you to replace the first period with one or more spaces. It's analogous to 2 + 4
, which is in fact 2.+(4) #=> 6
. (Try it.)
Related Topics
Eliminate Consecutive Duplicates of List Elements
How Does Activerecord Define Methods Compared to Attr_Accessor
Why Ruby Inject Method Cannot Sum Up String Lengths Without Initial Value
How to Decode a Cookie from the Header of a Websocket Connection Handshake? (Ruby)
How to Setup a Local Ssl Certificate and a Rails Application
How to Rename or Move Rails's Readme_For_App
Sinatra Does Not Start with Twitter Gem
Failed to Build Gem Native Extension - Extconf.Rb Not Found
Rails 3, Displaying Jpg Images from the Local File System Above Rails_Root
Erroneous "Insecure World Writable Dir Foo in Path" When Running Ruby Script
Rails SQL Query Builder... or Activerecord Query Builder
Openshift and Net-Ssh Incompatibility? (2.9.3-Beta1 VS 2.9.2)
What Does "Temps.Each(&:Valid)" Mean in Ruby
Unable to Install MySQL2 Gem on Bigsur
How to Run Code After Each Line in Ruby