Ruby variable name with double underscores
An initial underscore or double underscore basically indicates
"special/avoid overwrite" --meaning it's meant to reduce the
likelihood that someone else might define a method/attribute of the
same name. The most common occurrence is__send__
.
From Ruby Forum
What is @__instance__ in Ruby?
The underscore is a legal character in an identifier. It has no meaning whatsoever.
(There is one exception: local variables that start with an underscore will not generate a warning if they are unused.)
In other words: the meaning of @__instance__
is exactly the same as the meaning of @foobar
: there is no meaning.
Ruby naming convention / double underscore / useful stuff
This is a complete list for Ruby 2.1:
__callee__
(Kernel)__dir__
(Kernel)__method__
(Kernel)__id__
(BasicObject)__send__
(BasicObject)__ENCODING__
(keyword)__LINE__
(keyword)__FILE__
(keyword)
From delegate:
__getobj__
(Delegator)__setobj__
(Delegator)__getobj__
(SimpleDelegator)__setobj__
(SimpleDelegator)
From drb:
__drbref
__drburi
From irb:
__evaluate__
__exit__
From tk:
- All the methods start with a double underscore
Is it good practice having local variables starting with underscore?
Nothing wrong with your idea. But if I was having trouble distinguishing local vars from method calls, I would probably just force myself to always use ()
's on methods. (My team at work has discussed making this part of our coding standards).
a = thing # var
b = thing() # method
The possible advantage to this is readability to others. Someone may wonder at your leading _'s, but using ()
's on all method calls should be clear to everyone.
Use of underscores with splats in Ruby
A legal variable name is _
. And something like *_
is similar to *x
. The term a trailing underscore variable actually refers to the last variable name in a comma separated series of variables on the left side of an assignment statement, e.g.:
a, b, _ = [1, 2, 3, 4]
The splat operator has two uses:
- Explode an array into its individual items.
- Gather items into an array.
Which of those happens depends on the context that the splat operator is used in.
Here are the examples that the Ruby style guide says are bad:
a, b, _ = *foo
The trailing underscore variable in that example is unnecessary because you can assign the first two elements of foo
to the variables a
and b
by writing:
a, b = *foo
The underscore variable is used to say, I don't care about this variable, and therefore it isn't necessary in that example if all you want to do is assign to a
and b
.
The example also might be considered bad style because the *
operator isn't needed either(credit: Cary Swoveland):
a, b = [1, 2, 3]
p a, b
--output:--
1
2
The *
can be used on the right hand side to good effect like this:
x, y, z = 10, [20, 30]
p x, y, z
--output:--
10
[20, 30]
nil
x, y, z = 10, *[20, 30]
p x, y, z
--output:--
10
20
30
So, just keep in mind that in the rest of the examples from the style guide the *
is superfluous on the right hand side.
The next bad example is:
a, _, _ = *foo
Here is a more concrete example:
a, _, _ = *[1, 2, 3, 4]
p a, _
puts "-" * 10
a, _ = *[1, 2, 3, 4]
p a, _
--output:--
1
3
----------
1
2
The following shows the way the assignment works in the first section of the example:
a, _, _
^ ^ ^
| | |
[1, 2, 3, 4]
In any case, if you get rid of the second underscore variable on the left, then a
will be assigned the same thing. What about getting rid of both underscore variables?
a = *[1, 2, 3, 4]
p a
--output:--
[1, 2, 3, 4]
Nope. So the first underscore variable on the left appears to be necessary. However, there is another syntax to get the same result without using a trailing underscore variable:
a, = *[1, 2, 3, 4]
p a
--output:--
1
Therefore, the third bad example:
a, *_ = *foo
can also be written as:
a, = *foo
and thereby avoid a trailing underscore variable.
Finally, the style guide offers this cryptic advice:
Trailing underscore variables are necessary when there is a splat
variable defined on the left side of the assignment, and the splat
variable is not an underscore.
I think that may be referring to something like this:
*a = *[1, 2, 3, 4]
p a
--output:--
[1, 2, 3, 4]
If you want a
to be assigned the first three elements of the array, then you have to write:
*a, _ = *[1, 2, 3, 4]
p a
--output:--
[1, 2, 3]
For whatever reason, the parser cannot handle:
*a, = *[1, 2, 3, 4]
--output:--
*a, = *[1, 2, 3, 4]
^
1.rb:6: syntax error, unexpected '\n', expecting :: or '[' or '.'
Here is one of the good examples:
*a, b, _ = *foo
The trailing underscore variable is necessary there, IF you want to assign the second to the last element of foo to b
.
The following good examples are a little perplexing:
a, _b = *[1, 2, 3, 4]
a, _b, = *[1, 2, 3, 4]
Let's try them out:
a, _b = *[1, 2, 3, 4]
p a, _b
puts "-" * 10
a, _b, = *[1, 2, 3, 4]
p a, _b
--output:--
1
2
----------
1
2
In ruby, a variable name such as _b
is no different than a variable named _
or b
. In functional languages, like Erlang, the variables _
and _B
and B
have different effects--but not in Ruby.
By the way, I wouldn't spend five minutes learning that style--it's too esoteric.
What does an underscore between two variable mean?
Ruby's double-quoted string literals and symbol literals allow interpolation via #{...}
. It works like a placeholder. The result of an expression given within the parentheses is converted to a string and inserted at the given position:
"1 + 2 = #{1 + 2}"
#=> "1 + 2 = 3"
Back to your question:
What does an underscore between two variables mean?
Within a string, an underscore is a literal underscore, i.e. _
.
Your code creates a hash with dynamically created symbol key and string value:
type = 'foo'
data = { 'blah' => 'bar', 'blahblah' => 'baz' }
{ "#{type}_#{data['blah']}": "#{data['blahblah']}" }
#=> {:foo_bar=>"baz"}
There was a minor typo in your code: the :
must not have a trailing space.
Furthermore, interpolation is not needed if the string contains nothing else. If data['blahblah']
is a string, you can just write:
{ "#{type}_#{data['blah']}": data['blahblah'] }
And otherwise:
{ "#{type}_#{data['blah']}": data['blahblah'].to_s }
Related Topics
Str.Each in Ruby Isn't Working
Ruby on Rails Multiple Http Request at the Same Time
Stop Loading Page Watir-Webdriver
In Ruby, How to Get Instance Variables in a Hash Instead of an Array
Why Does a Rails App on Heroku Serve Assets via All.CSS and Locally via Individual Files
Ruby: Converting from Float to Integer in Ruby Produces Strange Results
Unable to Install MySQL2 Gem on Bigsur
React Error (Only a Reactowner Can Have Refs.)
How to Save Heroku Logs to Text File
How to Parse a Url and Extract the Required Substring
Testing Routes with Subdomain Constraints Using Rspec
No Such File to Load -- SQLite3/Sqlite3_Native
Ruby on Rails Incompatible Library
How to Set a Variable from a Helper Method for Inclusion in a SASS SCSS Stylesheet
Install Cocoapods Failed on MAC
Is the .Each Iterator in Ruby Guaranteed to Give the Same Order on the Same Elements Every Time